poj 2411 Mondriaan's Dream(状态压缩DP)
来源:互联网 发布:c语言密码程序 编辑:程序博客网 时间:2024/05/12 00:10
Description
Expert as he was in this material, he saw at a glance that he'll need a computer to calculate the number of ways to fill the large rectangle whose dimensions were integer values, as well. Help him, so that his dream won't turn into a nightmare!
Input
Output
Sample Input
1 21 31 42 22 32 42 114 110 0
Sample Output
10123514451205
Source
题意:给出一个n*m的棋盘,及一个小的矩形1*2,问用这个小的矩形将这个大的棋盘覆盖有多少种方法。
思路:
由于我们放置小矩形的时候可以横着放也可以竖着放,那么就会产生不同的方法,但是必须满足不产生空的未覆盖的空格子。
首先我们用二进制1 0表示在某一个问题放置或者不放置,那么有m列的棋盘,每一行有2*m个状态了,我们现在就找出每行之间的规律。
对于一个矩形有3种方法:横放,竖放,不放。由于第i行只跟第i-1行的放置有关系,因为我们必须保证第i-1行使放满的,现在用dp[i][state]表示第i行
状态为state的方法,那么dp[i][curstate]=sum{dp[i-1][prestate]}.
1 横放
如果第i行第d列我们选择横放,那么第i行的第d列及d+1列都是1了,第i-1行第d列及d+1列也都必须为1(保证是满的),及状态转移为:
d=d+2,curstate=curstate<<2|3,prestate=prestate<<2|3.
2竖放
第i行第d列我们选择竖放,那么第i行第d列为1,第i-1行d列必须是0,(因为我们是竖着放的,如果前一行不是空的如何能放下呢),状态转移:
d=d+1,curstate=curstate<<1|1,prestate=prestate<<1.
3不放
第i行第d列不放,那么第i-1行d列肯定是1,(保证是满的),状态转移:
d=d+1,curstate=curstate<<1,prestate=prestate<<1|1.
这个题目采用记忆化搜索,对已经计算出的状态值方法记录,还有就是初始化的时候将dp[0][2<<m-1]=1,这样第0行使放满的,就不用单独进行初始化了(单独初始化的时候,由于是第一行,不存在竖着放的可能)。
我们的目标就是求dp[n][2<<m-1]了。
代码:
#include<cstdio>#include<algorithm>#include<cstring>#define LL long longusing namespace std;int n,m,len;int path[14000][2];LL dp[15][1<<11];void dfs(int l,int now,int pre){ if(l>m) return; if(l==m) { path[len][0]=pre; path[len++][1]=now; return; } dfs(l+2,(now<<2)|3,(pre<<2)|3); //横放 dfs(l+1,(now<<1)|1,pre<<1); //竖放 dfs(l+1,now<<1,(pre<<1)|1); //不放}int main(){ while(~scanf("%d%d",&n,&m)) { if(!n&&!m) break; if(n*m%2) { printf("0\n"); continue; } len=0; dfs(0,0,0); memset(dp,0,sizeof(dp)); dp[0][(1<<m)-1]=1; for(int i=0;i<n;i++) for(int j=0;j<len;j++) { dp[i+1][path[j][1]]+=dp[i][path[j][0]]; } printf("%I64d\n",dp[n][(1<<m)-1]); }}
- POJ 2411 Mondriaan's Dream 状态压缩(DP)
- poj 2411 Mondriaan's Dream (状态压缩dp 入门)
- POJ 2411 Mondriaan's Dream (状态压缩DP)
- poj 2411 Mondriaan's Dream(状态压缩DP)
- POJ 2411 Mondriaan's Dream (dp + 状态压缩)
- poj 2411 Mondriaan's Dream (状态压缩dp)
- poj 2411 Mondriaan's Dream(状态压缩+dp)
- POJ - 2411 Mondriaan's Dream(状态压缩DP)
- poj 2411 Mondriaan's Dream(状态压缩DP)
- poj 2411 Mondriaan's Dream(状态压缩dp)
- poj 2411 Mondriaan's Dream (状态压缩dp)
- POJ 2411 Mondriaan's Dream 状态压缩DP
- POJ 2411 Mondriaan's Dream 状态压缩dp
- POJ 2411 Mondriaan's Dream(DP---状态压缩)
- poj 2411/hdu 1400 Mondriaan's Dream 状态压缩dp
- HDOJ 1400 & POJ 2411 - Mondriaan's Dream 状态压缩DP
- poj 2411 Mondriaan's Dream(状态压缩dp)
- [poj 2411]Mondriaan's Dream[状态压缩DP]
- 打造Android万能的软件更新库,修改只要一点点
- 设计模式-建造者模式
- C/C++语言编译过程
- codeforces637c密码
- 使用httpclient 4.3实现 socks5 proxy + 身份验证
- poj 2411 Mondriaan's Dream(状态压缩DP)
- Netty示例
- c++指针复习
- Hibernate4二级缓存Ehcache配置
- luogu1541乌龟棋
- 新闻类客户端代码阅读笔记
- 大话实时计算(二)
- android加密算法
- 基础概念5