状态压缩DP——AcWing 291. 蒙德里安的梦想

状态压缩DP

定义

状态压缩DP是一种利用二进制数来表示状态的动态规划算法。它通过将状态压缩成一个整数,从而减少状态数量,提高算法效率。

运用情况

状态压缩DP通常用于解决具有状态转移和最优解性质的问题,例如组合优化、图论、游戏等问题。它的基本思想是将问题的状态表示为一个二进制数,其中每一位表示一个元素或一个状态。通过对二进制数的位运算,可以方便地进行状态转移和最优解的计算。

注意事项

  1. 状态表示的合理性:确保状态表示能够准确地反映问题的特征和约束条件。
  2. 状态转移的正确性:仔细设计状态转移方程,确保状态转移的正确性和有效性。
  3. 边界情况的处理:考虑边界情况,如初始状态、终止状态等,进行特殊处理。
  4. 空间复杂度的控制:由于状态数量可能很大,需要注意控制空间复杂度,避免内存溢出。
  5. 位运算的优化:合理使用位运算,提高算法的效率。

解题思路

  1. 状态表示:将问题的状态用二进制数表示,每个二进制位表示一个元素或状态。
  2. 状态转移:根据问题的规则,设计状态转移方程,通过位运算实现状态的转移。
  3. 初始化:确定初始状态,并进行相应的初始化操作。
  4. 计算最优解:通过递推或迭代的方式,计算每个状态的最优解。
  5. 输出结果:根据问题的要求,输出最终的最优解。

如何处理状态的溢出和下溢

  • 状态压缩:使用二进制数来表示状态,通过位运算来进行状态转移和计算。这种方法可以大大减少状态的数量,提高算法的效率。
  • 判断状态:在进行状态转移和计算时,需要判断当前状态是否合法。如果当前状态不合法,则需要进行特殊处理,例如忽略该状态或者将其标记为已访问。
  • 初始化状态:在进行状态转移和计算时,需要对状态进行初始化。如果状态的初始值设置不合理,则可能会导致状态的溢出或下溢。
  • 边界情况处理:在进行状态转移和计算时,需要考虑边界情况。如果边界情况处理不当,则可能会导致状态的溢出或下溢。

AcWing 291. 蒙德里安的梦想 

题目描述

291. 蒙德里安的梦想 - AcWing题库

运行代码

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 12, M = 1 << N;
int n, m;
LL f[N][M];
bool st[M];
vector<int> state[M];
int main()
{while(cin >> n >> m, n || m){for(int i = 0; i < 1 << n; i++){int ans = 0;bool is = true;for(int j = 0; j < n; j++){if(i >> j & 1){if(ans & 1){ is = false; break;}ans = 0;}else ans ++;}if(ans & 1) is = false;st[i] = is;}for(int i = 0; i < 1 << n; i++){state[i].clear();for(int j = 0; j < 1 << n; j++)if((i & j) == 0 && st[i | j])state[i].push_back(j);}memset(f, 0, sizeof f);f[0][0] = 1;for(int i = 1; i <= m; i++)for(int j = 0; j < 1 << n; j++)for(auto k : state[j])f[i][j] += f[i - 1][k];cout << f[m][0] << endl;}return 0;
}

代码思路

  1. 输入处理:首先,程序通过 cin >> n >> m 获取两个整数,其中 n 表示问题规模(通常是与二进制位数相关),m 是一个操作次数或阶段数。当 n 或 m 不为零时,继续执行。
  2. 初始化状态:接下来,程序遍历所有 1 << n(即 2^n2n)种二进制状态(用整数表示),检查每个状态是否满足特定条件。这里的条件是:对于一个状态(二进制数),如果从左到右连续的0后面紧接着是1,则认为该状态无效(标记为 false,存储在数组 st[] 中),否则为有效(标记为 true)。这是通过累计0的个数并在遇到1时检查累计值的奇偶性来判断的。
  3. 构建状态转移图:然后,程序构建一个“状态转移图”。对于每一个状态 i,找到所有与 i 按位或 (|) 后仍能保持有效的状态 j,并将这些状态添加到 state[i] 这个向量中。这一步实际上是为动态规划准备状态转移的基础,确保从一个有效状态通过某个操作可以转移到另一个有效状态。
  4. 动态规划计算:初始化动态规划数组 f[][],其中 f[i][j] 表示进行了 i 次操作后到达状态 j 的方案数。初始时,只有一种方法不进行任何操作到达初始状态(全0状态),即 f[0][0] = 1。
  5. 遍历 m 次操作,对于每一次操作,以及当前可达的所有状态 j,考虑从所有能转移到 j 的前驱状态 k(存储在 state[j] 中)经过一次操作到达 j 的方案数,并累加到 f[i][j] 上。
  6. 输出结果:最后,输出进行了 m 次操作后到达初始状态(全0状态)的方案数,即 f[m][0]。
  7. 总结:这段代码的核心思想是使用动态规划和位操作来解决一个组合计数问题,特别是在有限状态空间内寻找满足特定转移规则的路径数量。通过构建状态转移关系并迭代计算,高效地得到了问题的解。

改进思路

  1. 减少状态空间大小:如果题目条件允许,可以尝试减少需要枚举的状态数量。不过,从当前代码逻辑看,似乎已经利用了问题的特性(通过位运算处理状态转移),直接减小状态空间较为困难。

  2. 内存优化:由于 f[][]st[] 数组的大小与 n 直接相关,且随着 n 增大非常快,可以考虑使用滚动数组或者空间压缩技巧来减少内存使用。对于 f[][],实际上每一阶段只需要上一阶段的状态,因此可以使用一维数组滚动更新。

  3. 避免重复计算:当前代码在计算状态转移时,对于每个状态 j,都会遍历其所有可能的前驱状态并累加方案数。如果存在大量重复计算的情况,可以考虑使用记忆化搜索或更高效的数据结构来存储中间结果。

  4. 代码可读性和维护性:增加注释,对关键变量和步骤进行解释,使代码更易于理解和维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/32360.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI大眼萌探索 AI 新世界:Ollama 使用指南【1】

在人工智能的浪潮中&#xff0c;Ollama 的出现无疑为 Windows 用户带来了一场革命。这款工具平台以其开创性的功能&#xff0c;简化了 AI 模型的开发与应用&#xff0c;让每一位爱好者都能轻松驾驭 AI 的强大力量。大家好&#xff0c;我是AI大眼萌&#xff0c;今天我们将带大家…

GPT-4o一夜被赶超,Claude 3.5一夜封王|快手可灵大模型推出图生视频功能|“纯血”鸿蒙大战苹果AI|智谱AI“钱途”黯淡|月之暗面被曝进军美国

快手可灵大模型推出图生视频功能“纯血”鸿蒙大战苹果AI&#xff0c;华为成败在此一举大模型低价火拼间&#xff0c;智谱AI“钱途”黯淡手握新“王者”&#xff0c;腾讯又跟渠道干上了“美食荒漠”杭州&#xff0c;走出一个餐饮IPOGPT-4o一夜被赶超&#xff0c;Anthropic推出Cl…

力扣SQL50 查询结果的质量和占比 AVG(条件)

Problem: 1211. 查询结果的质量和占比 &#x1f468;‍&#x1f3eb; 参考题解 Code select query_name,round(avg(rating/position),2) as quality,round(100 * avg(rating < 3), 2) as poor_query_percentage from Queries group by query_name -- 到此结束过不了最后一…

PHP发送HTML邮件的步骤?设置模板的技巧?

PHP发送HTML邮件怎么设置模板&#xff1f;如何用PHP群发邮件&#xff1f; PHP提供了强大的功能来发送HTML格式的电子邮件&#xff0c;这在需要发送格式化内容的邮件时特别有用。AokSend将详细介绍PHP发送HTML邮件的步骤&#xff0c;涵盖了必要的准备工作和实际操作过程。 PHP…

MySQL操作语句练习【经典20题】

emp 表视图 dept 表视图 题目 1.请从表EMP中查找工种是职员CLERK或经理MANAGER的雇员姓名、工资。 2.请在EMP表中查找部门号在10&#xff0d;30之间的雇员的姓名、部门号、工资、工作。 3.请从表EMP中查找姓名以J开头所有雇员的姓名、工资、职位。 4.请从表EMP中查找工资低…

ffmpeg音视频开发从入门到精通——ffmpeg日志及目录操作

文章目录 FFMPEG1. 操作日志2. 文件移动和删除3. 操作目录重要函数 FFMPEG 1. 操作日志 日志级别 AV LOG ERROR AV LOG WARNING AV LOG INFO AV LOG DEBUG cmake_minimum_required(VERSION 3.27) project(FFmpeg_exercise) set(CMAKE_CXX_STANDARD 14)# 定义FFmpeg的安装路…

转--Hadoop集群部署案例

模块简介 本模块主要练习Hadoop集群部署。 模块知识 ● 使用Linux基础命令 ● Hadoop集群搭建部署知识 环境准备 三台CentOS7操作系统的虚拟机 可以是3个Docker容器&#xff0c;也可以是三个VMWare/VirtualBox的虚拟机。三台虚拟机的最低配置为1核1G 20G。如果是虚拟机中…

MK米客方德SD NAND的掉电保护机制

随着科技的飞速发展&#xff0c;数据存储设备在我们的生活和工作中扮演着越来越重要的角色。然而&#xff0c;数据安全问题也随之而来&#xff0c;尤其是面对突然的电源故障或意外断电&#xff0c;我们宝贵的数据可能会面临丢失的风险。MK米客方德公司深知这一点&#xff0c;因…

Linux中tar压缩与解压缩

TAR是Unix/Linux中常用的归档工具&#xff0c;它可以对文件或目录进行打包但不压缩&#xff0c;或者配合其他工具进行压缩。 压缩文件或目录 以下是一些基本的tar压缩命令&#xff1a; 1.压缩单个文件&#xff1a; tar -cvf archive.tar file1 2.压缩多个文件&#xff1a; t…

导入别人的net文件报红问题

1. 使用cmd命令 dotnet --info 查看自己使用的SDK版本 2.直接找到项目中的 global.json 文件&#xff0c;右键打开&#xff0c;直接修改版本为本机的SDK版本&#xff0c;就可以用了

CPU飙升100%怎么办?字节跳动面试官告诉你答案!

小北说在前面 CPU占用率突然飙升是技术人员常遇到的一个棘手问题&#xff0c;它是一个与具体技术无关的普遍挑战。 这个问题可以很简单&#xff0c;也可以相当复杂。 有时候&#xff0c;只是一个死循环在作祟。 有时候&#xff0c;是死锁导致的。 有时候&#xff0c;代码中有…

windows设置开机启动项

将文件放到下面路径即可实现每次开机启动 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

【最新】2025QS世界大学排名数据与得分明细数据集

数据简介&#xff1a;QS排名由Quacquarelli Symonds公司发布&#xff0c;是全球最具影响力的大学排名之一。它每年根据学术声誉、雇主声誉、师生比例、文献引用率、国际师资和国际学生比例等多项指标&#xff0c;对全球大学进行评估和排序。旨在为学生、学者和雇主提供权威的高…

如何使用小猪APP分发进行在线封装

什么是在线封装&#xff1f; 在线封装&#xff0c;顾名思义&#xff0c;就是通过网络将应用程序进行打包处理。这个过程不仅能节省时间&#xff0c;还能大大提升工作效率&#xff0c;让开发者专注于应用本身的优化。 小猪app封装www.ppzhu.net 为什么选择小猪APP分发&#xf…

YOLOv8改进 | SPPF | 双通道特征处理的池化结构——SPPFCSPC【全网独家】

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有40篇内容&#xff0c;内含各种Head检测头、损失函数Loss、…

java干货,spring声明式事务

文章目录 一、编程式事务1.1 什么是编程式事务1.2 编程式事务的优缺点 二、声明式事务2.1 什么是声明式事务2.2 声明式事务的优点2.3 Spring 事务管理器2.4 spring 声明式事务使用 一、编程式事务 1.1 什么是编程式事务 编程式事务是指通过手动编写程序来管理事务&#xff0c…

富唯智能打造的AGV搬运机器人转运机器人

AGV搬运机器人&转运机器人 AGV搬运机器人&#xff0c;内部搭载ICD系列核心控制器&#xff0c;拥有不同的移载平台&#xff0c;负载最高可达 1000kq;重复精度高达5mm;支持 Wi-Fi漫游&#xff0c;实现更稳健的网络数据交互;无轨化激光 SLAM 导航&#xff0c;配合 3D 避障相机…

CompletableFuture 基本用法

一、 CompletableFuture简介 CompletableFuture 是 Java 8 引入的一个功能强大的类&#xff0c;用于异步编程和并发处理。它提供了丰富的 API 来处理异步任务的结果&#xff0c;支持函数式编程风格&#xff0c;并允许通过链式调用组合多个异步操作。 二、CompletableFuture中…

通用大模型的低代码平台——3分钟内快速搭建一个邮件提醒工具

文章目录 ⭐前言⭐node-koa开发一个发送邮件的api⭐百度智能云控制面板&#x1f496; 发送邮件的组件配置&#x1f496; 配置应用发布 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;通用大模型的低代码平台——3分钟内快速搭建一个智能股票分析邮件提醒工具。…

Linux环境搭建之CentOS7(包含静态IP配置)

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;虚拟机 &#x1f320; 首发时间&#xff1a;2024年6月22日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e; 安装VMw…