蒙德里安的梦想

蒙德里安的梦想

算法标签

状态压缩dp

题目大意:求把 N×M的棋盘分割成若干个1×2 的的小长方形,有多少种方案。

思路分析: 首先,注意到,我们直接考虑如何切割整个棋盘为若干个1x2的长方形是比较困难的,因此,我们可以把整个棋盘划分为若干个1x1的小格子,那么,问题就转化为了用1x2的小长方形去将整个棋盘填充满,总共有多少种方案。此外,注意到,当我们将所有横向的小长方形都已经摆放(填充)完成后,所有纵向的小长方形的摆放方式也就唯一确定了,那么,总的方案数就等于摆完所有横向长方形的方案数。所以,我们只用考虑如何枚举横向长方形的摆放即可

模型: 
这个问题属于状态压缩dp问题的第一大类:基于连通性的dp,也可以叫做棋盘式dp。我们首先考虑如何定义(设计)状态,也就是如何进行状态表示。 我们按列来枚举横向小长方形的摆放情况。f为dp数组。若当前我们需要摆放的列是第i 列,那么第i列在摆放的时候只和第i-1列有关(因为只有i-1列的小长方形可能伸到第i列,影响第i 列的摆放)。因此,我们设f[i][j]表示:前i-1列已经摆放完毕(不能再改了),当前要对第i列进行横向小长方形的摆放,且前一列伸出一个小方格是j 的情况下的方案数。如下图所示:

j是一个n位的二进制数,上图对应的j为01,代表第i-1列第0行伸出了一个小方格(所以j的第0位为1)。那么,这个状态表示的集合就是:

所有前i-1列已经摆放完毕且第i-1列伸出小方格的状态为j的情况下的摆放方案

f[i][j]记录的是集合中的方案总数(根据题目所求来确定)

接下来考虑如何进行状态计算(转移),所谓状态计算,就是对集合进行划分,而划分的依据就是“最后一个不同点”。根据我们上面f[i][j]的定义,第i-1列横向小长方形的摆放方案是确定的(因为二进制数j代表了其摆放的情况),所以,最后一个不同点就是第i-2列的摆放情况。因此,我们将依据第i-2列的摆放情况对f[i][j]所表示的大集合进行划分,将它划分成1<<n个子集。但是,这些子集不一定都可以转移过来,因此,我们需要判断哪些子集所对应的状态才可以转移到我们当前的状态。为了方便之后的表示,我们设a为第i-1列的“摆放情况”,b为第i-2列的”摆放情况”。那么,合法的状态需要满足以下两个条件:1:a&b==0,即二者的二进制不能有某一位同时为1(意思是第i-2列和第i-1列不能在同一行同时摆放上横向的小长方形(同时伸出小格子),因为这样,第i-2列伸出的小方格就会”阻碍”到第i-1列的摆放,是不合法的)

2: 由于第i-1列横向的格子已经摆放完毕,那么其纵向格子的摆放方式也已经确定,所以,我们摆完横向的小长方形后,剩下连续的空格子的数量不能是奇数,否则就不能通过摆放纵向小长方形将整个棋盘填满了。所以,我们需要算出每个状态下连续0的个数。这个条件的判断可以通过”预处理完成”。

另外,我们可以预处理出所有合法(能够进行状态转移的状态),方便后续状态的计算。

这样,f[i][j]就等于所有能转移到它的状态所对应的方案数的总和。

我们最终的答案就是:f[m][0]。注意,下标从0开始,所以,它代表所有前m–1列(也就是整个棋盘)已经摆完,并且伸出格子的情况为0(没有伸出棋盘,是合法的)的方案总数。并且,dp数组的初始化为:f[0][0]=1(因为摆第0列时不存在前一列会伸出来,也就表示当前列没有横着摆的小长方形,所以只有都竖着摆放这一种情况)

c++代码

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N=12,M=1<<N;
typedef long long LL;
int n,m,st[M];//st==1表示当前状态是合法的
LL f[N][M];//极限状态下可能会爆int
vector<int>truestate[M];//二维数组,truestate[i]中存储所有可以转移到状态i的状态,方便通过循环递推计算出所有状态的值
//vector<vector<int>>truestate(M);
int main()
{while(cin>>n>>m,n||m) //逗号表达式的值为逗号之后的值{for(int i=0;i<1<<n;i++)//枚举所有状态,判断其是否有连续奇数个0{st[i]=1;int cnt=0;//连续奇数0的个数for(int j=0;j<n;j++)if(i>>j&1)//i的第j位是1,前一段连续的0终止了{if(cnt&1)//cnt为奇数{st[i]=0;break;}cnt=0; //继续统计下一段连续0的个数,要将上一段的数量清零(实际上不清0也可以AC,因为加一个偶数不会影响奇偶性(奇数会break))}elsecnt++;if(cnt&1)//判断最后一段连续0的个数的奇偶性st[i]=0;}for(int i=0;i<1<<n;i++)//计算出所有的truestate 这里i枚举的是状态定义中对应的第i-1列的情况,j枚举的是第i-2列对应的情况{truestate[i].clear();for(int j=0;j<1<<n;j++)if(!(i&j)&&st[i|j])//只要二者有一位为1,连续0就会被隔断,所以,第状态定义中第i-1列实际的状态是i|jtruestate[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:truestate[j])//遍历所有可以转移到j的状态f[i][j]+=f[i-1][k];//状态计算(转移)cout<<f[m][0]<<endl;}return 0;
}

时间复杂度分析:dp问题的时间复杂度公式 =状态数量× 状态转移(计算)

状态表示 f[i][j] 第一维i可取11,第二维j(二进制数)可取2的11次方,根据乘法原理,可计算出状态数量
状态转移 也是2的11次方(每个状态最多可划分成这么多个子集)
所以总的时间复杂度约等于=4e7

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

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

相关文章

Java重试的几种写法

在开发Java应用程序时&#xff0c;经常需要处理一些可能失败的操作&#xff0c;例如数据库连接、网络请求等。为了增加程序的健壮性和容错性&#xff0c;我们可以使用重试机制来尝试多次执行失败的操作。本文将介绍Java中常见的7种重试机制&#xff0c;并提供相应的Java示例。 …

Android JNI--C++基础

1,基础结构 C标准支持 #include <iostream>C语言的标准支持 #include <stdio.h> 命名空间 C的特性 std C系统的命名空间 也可以自定义 using namespace std; C中命名空间的作用类似于操作系统中的目录和文件的关系&#xff0c;由于文件很多&#xff0c;不便管…

章节2:客户端的Cookie

章节2&#xff1a;客户端的Cookie 无状态的影响 现实&#xff1a;每个请求都是独立的 需求&#xff1a;保持会话 cookie内容 key/value 格式&#xff0c;例如&#xff1a; namewuya id99 islogin1 cookie怎么产生 Cookie格式 Set-Cookie&#xff1a;第一次访问&#…

java版工程项目管理系统源码+系统管理+系统设置+项目管理+合同管理+二次开发em

​ 鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部…

IP路由基础+OSPF 基础

IP路由 RIB与FIB RIB&#xff1a;Routing Information Base&#xff0c;路由信息库 &#xff0c;路由器的控制平面 FIB&#xff1a;Forwarding Information Base&#xff0c;转发信息库&#xff0c;路由器的数据平面 路由信息库主要是记录直连路由以及协议宣告的路由信息&am…

如何给a-table增加列宽拖动功能

对于table的列宽设置 相信用过的人都知道&#xff0c;想要设置得很完美&#xff0c;几乎是不现实的&#xff0c;因为总有数据或长或短&#xff0c;那我们应该如何优化它呢&#xff1f;那便是让用户自行拖动列宽&#xff0c;从而能看全table的数据&#xff0c;但是对于antd-vue …

恒运资本:股票印花税下降有什么影响?什么原因导致下降?

在进行股票教育过程中是需求收取必定的手续费的&#xff0c;比如说买卖佣钱、印花税、过户费等等。那么股票印花税下降有什么影响&#xff1f;什么原因导致下降&#xff1f;下面就由恒运资本为大家剖析&#xff1a; 股票印花税下降有什么影响&#xff1f; 1、对于企业&#xf…

位置参数 关键字参数

在Python中&#xff0c;函数参数可以按照位置或关键字来传递。这导致了两种主要的参数类型&#xff1a;位置参数和关键字参数。 位置参数: 这是最常见的参数类型&#xff0c;当我们调用函数时&#xff0c;传递给函数的参数值是按照它们的位置来确定的。例如&#xff0c;def fun…

vscode运行python报错:ModuleNotFoundError:No module named ‘xxx‘

在乌班图上使用pycharm的时候&#xff0c;pycharm总是莫名其妙卡死&#xff0c;又说是搜狗输入法的锅&#xff0c;又说别的原因&#xff0c;一气之下不用pycharm,转到vscode上&#xff0c;没想到出现了如下报错。 就是vscode在运行python的时候&#xff0c;自定义模块的调用无…

【C语言】经典题目(四)

HI&#xff0c;大家好~&#x1f61d;&#x1f61d;这是一篇C语言经典题目的博客。 更多C语言经典题目及刷题篇&#xff0c;可以参考&#xff1a; &#x1f338; 【C语言】经典题目(一) &#x1f338; 【C语言】经典题目(二) &#x1f338; 【C语言】经典题目(三) &#x1f338;…

vue3中的自定义指令用法

我们都知道vue2中自定义指令全局和局部是这样写的 局部&#xff1a; 全局&#xff1a; 可vue3写法发生改变&#xff0c;如下&#xff1a; 全局&#xff1a; 局部&#xff1a;

音视频 FFmpeg命令行搭建

文章目录 一、配置二、测试 一、配置 以FFmpeg4.2.1 win32为例 解压ffmpeg-4.2.1-win32-shared.zip 拷⻉可执⾏⽂件到C:\Windows拷⻉动态链接库到C:\Windows\SysWOW64 注&#xff1a;WoW64 (Windows On Windows64)是⼀个Windows操作系统的⼦系统&#xff0c;被设计⽤来处理许…

【网络】自定义协议 | 序列化和反序列化 | Jsoncpp

本文首发于 慕雪的寒舍 以tcpServer的计算器服务为例&#xff0c;实现用jsoncpp来进行序列化和反序列化 阅读本文之前&#xff0c;请先阅读 自定义协议 | 序列化和反序列化 | 以tcpServer为例 1.安装jsoncpp 我所用的系统是centos7.6&#xff0c;先用下面的命令查找相关的包 …

chrome插件开发实例07- Vue调试插件vue-devtools

目录 一、为什么使用vue-devtools插件 二、如何安装 三、使用源码方式,安装Vue-devtools插件

图的遍历之 深度优先搜索和广度优先搜索

深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search)&#xff0c;和树的先序遍历比较类似。 它的思想&#xff1a;假设初始状态是图中所有顶点均未被访问&#xff0c;则从某个顶点v出发&#xff0c;首先访问该顶点&#xff0c;然后依次从它的各…

Element组件浅尝辄止2:Card卡片组件

根据官方说法&#xff1a; 将信息聚合在卡片容器中展示。 1.啥时候使用&#xff1f;When? 既然是信息聚合的容器&#xff0c;那场景就好说了 新建页面时可以用来当做页面容器页面的某一部分&#xff0c;可以用来当做子容器 2.怎样使用&#xff1f;How&#xff1f; //Card …

目标跟踪与检测后进行 OpenCV 人脸识别 ,马赛克

文章大纲 简介模型下载地址ONNX 静态与动态 参数OpenCV 中支持的 人脸检测、识别Face detection 人脸检测YuNetFace recognition 人脸识别sFace目标检测,跟踪 后的人脸模糊问题汇总不支持动态输入的问题参考文献与学习路径简介 OpenCV 4.5.4版本收录了一个基于深度学习神经网…

分布式应用:Zabbix代理服务器与SNMP监控

目录 一、理论 1.分布式监控 2.Zabbix代理服务器部署 3.配置 agent 使用 proxy 4.设置 Zabbix-SNMP 监控 二、实验 1.Zabbix代理服务器部署 2.配置 agent 使用 proxy 3.设置 Zabbix-SNMP 监控 三、总结 一、理论 1.分布式监控 &#xff08;1&#xff09;作用&#x…

Docker安装Mysql、Redis、nginx、nacos等环境

相关系列文章&#xff1a; 1、DockerHarbor私有仓库快速搭建 2、DockerJenkinsHarbor 1、服务器 Ip部署内容说明192.168.88.7Docker、Mysql、redis、nacosnode1192.168.88.8Docker、Mysql、redis、nacosnode2192.168.88.9Docker、redis、nacos、nginxnode3 2、安装PXC8.0 Mys…

PHP实现在线进制转换器,10进制,2、4、8、16、32进制转换

1.接口文档 2.laravel实现代码 /*** 进制转换计算器* return \Illuminate\Http\JsonResponse*/public function binaryConvertCal(){$ten $this->request(ten);$two $this->request(two);$four $this->request(four);$eight $this->request(eight);$sixteen …