状态压缩dp poj2411 1*2砖块
来源:互联网 发布:股票数据api https 编辑:程序博客网 时间:2024/06/05 10:40
一开始想着用00, 11表示同一个砖,但是这样的话状态转移就难了,,然后看题解。题解的状态就不会冲突。
- /*分析:用1*2的砖去恰好铺满n*m的空间,对于第k行第j列,有3种情况将该点铺满
- 1:由第k-1行第j列砖竖着铺将第k行第j列铺满
- 2:由第k行第j列被横铺砖铺满
- 3:第k行第j列砖竖着铺将该点铺满
- 所以对于每一列的情况其实有两种(1,0)表示该点铺砖还是不铺
- 而对于每一列必须到达的状态只有一种,就是被铺满(1)
- 但是由上述3种情况将铺满方式分成两种:
- 0和1表示被k-1行j列竖铺铺满和在k-1行被横铺铺满
- 对于每一行列举每一种到达的状态j,dp[j]表示到达该状态有多少种情况
- 分析对于第k-1行状态j:10000111
- 需要到达第k行状态i: 01111011
- 如果需要到达第k行j列状态是0,则必须第k-1行该点状态不能是0,否则一定是连续两列竖放冲突
- 所以到达第k-1行该点只能是1,也就是说i|j一定每一位是1,也可以一步步判断是否满足第k行j列是0第k-1行j列是1
- 如果需要到达第k行状态j列是1,则假如第k-1行该点是0,则该点状态可以到达,继续判断j+1列
- 假如第k-1行该点是1,则第k行j列的1一定是横铺到达的,所以k行第j+1列一定也被铺满为1
- 从而第k-1行j+1列一定不能竖铺,必须被横铺铺满,所以也是1.
- 于是综合的第k行j列和第k-1行j列的关系(每一行每一列都表示到达的状态)
- 1:下面这种情况从第j列继续去判断j+1列
- 1
- 0
- 2:下面这种情况从第j列继续去判断j+1列
- 0
- 1
- 3:下面这种情况从第j列判断第j+1列是否全是1,然后继续判断第j+2列
- 1
- 1
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <string>
- #include <queue>
- #include <algorithm>
- #include <map>
- #include <cmath>
- #include <iomanip>
- #define INF 99999999
- typedef long long LL;
- using namespace std;
- const int MAX=(1<<11)+10;
- int n,m;
- LL temp[MAX],dp[MAX],bin[15];
- bool mark[MAX];
- bool check(int i){
- while(i){
- if(i&1){
- i>>=1;
- if(!(i&1))return false;//第j列是1则第j+1列必须是1
- i>>=1;//继续判断下一列
- }else i>>=1;//继续判断下一列
- }
- return true;
- }
- void Init(){
- memset(mark,false,sizeof mark);
- memset(temp,0,sizeof temp);
- for(int i=0;i<bin[m];++i){//初始化第一行和可以到达什么状态
- if(check(i))temp[i]=1,mark[i]=true;
- }
- }
- void DP(){
- for(int k=2;k<=n;++k){
- for(int i=0;i<bin[m];++i)dp[i]=0;
- for(int i=0;i<bin[m];++i){
- for(int j=0;j<bin[m];++j){
- if((i|j) != bin[m]-1)continue;//每一位或之后必须每一位是1(综合前面3种情况和分析可知) //起码让他要全为1
- if(!mark[i&j])continue;//由初始化和前面分析三种情况分析可知i&j必须得到和初始化可以到达的状态一样才行 //然后要他不出现连续3个奇数的情况
- dp[i]+=temp[j];//i可以从j到达,则增加j的方案数 //
- }
- }
- for(int i=0;i<bin[m];++i)temp[i]=dp[i]; //相当于滚动数组,是的temp为上一列的数组。
- }
- }
- int main(){
- bin[0]=1;
- for(int i=1;i<12;++i)bin[i]=2*bin[i-1];
- while(~scanf("%d%d",&n,&m),n+m){
- if(n<m)swap(n,m);//始终保持m<n,提高效率
- Init();
- DP();
- printf("%lld\n",temp[bin[m]-1]);//输出最后一行到达时的状态必须全部是1
- }
- return 0;
- }
0 0
- 状态压缩dp poj2411 1*2砖块
- poj2411之用1*2砖块铺满n*m-状态压缩dp
- poj2411之用1*2砖块铺满n*m-状态压缩dp
- POJ2411 状态压缩DP
- poj2411 状态压缩dp
- POJ2411(状态压缩DP)
- POJ2411 状态压缩dp
- poj2411(状态压缩dp)
- POJ2411(状态压缩DP)
- poj2411状态压缩dp训练2——A
- poj2411 Mondriaan's Dream 状态压缩dp
- poj2411 Mondriaan's Dream 状态压缩dp
- 【poj2411】Mondriaan's Dream 状态压缩dp
- poj 2411 状态压缩DP 铺砖块
- 【POJ2411】Mondriaan's Dream-状态压缩DP(插头DP?)
- Poj2411 状态压缩
- poj2411 DP压缩
- 状态压缩DP poj2411 矩形填充木块问题
- Java基础(String类)
- 了解HTTP,一篇文章就够了
- **抢答器**
- common-backend
- Vue.js实现多条件筛选、搜索、排序及分页的表格功能
- 状态压缩dp poj2411 1*2砖块
- 【Python】scikit-learn教程
- Kickstart 2017 A. Square Counting
- python开发笔记
- Qt QWidget实现开关控件SwithButton(SlipButton)
- 2017.3.6 地精部落 思考记录
- Android四大基本组件及生命周期介绍
- 体验JVM编译Java文件
- java企业网站源码,模版,有前后台,springmvcSSM,生成静态化