zoj2563 Long Dominoes(状压dp)
2017-05-03 01:15
295 查看
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1563
Find the number of ways to tile an m*n rectangle with long dominoes – 3*1 rectangles.
Each domino must be completely within the rectangle, dominoes must not overlap (of course, they may touch each other), each point of the rectangle must be covered.
1.横着放 now 1 1 1 sup 1 1 1是sup111 suup111转移而来
2.竖着放:now=1 sup= 1时候suup 0 sup 0转移来
3.不放得第一种: now = 0 sup = 1: suup = 1 sup = 1转移来(上面都放好了)
第二种:now = 0 sup = 0: suup = 1 sup = 0转移来 (i+1行会竖着放)
Find the number of ways to tile an m*n rectangle with long dominoes – 3*1 rectangles.
Each domino must be completely within the rectangle, dominoes must not overlap (of course, they may touch each other), each point of the rectangle must be covered.
题意:
用1*3得砖铺满整个n*m方格得方法有多少种tip:
dp[I][s][t]表示到第I行,I行状态为s 上一行为t 这个状态就是这一行的n个铺了还是没谱(0/1)那每个是由谁转移来的呢,,1.横着放 now 1 1 1 sup 1 1 1是sup111 suup111转移而来
if(col + 3 <= m ){ if( (tsup & (1 << (col+1)) )&& ( (1 << (col+2)) & tsup) && (tsup & (1 << (col)) ) ){ if( (now & (1 << (col+1)) )&& ( (1 << (col+2)) & now ) && (now & (1 << (col)) ) ) dfs(fl,col+3,suup|(1<<col)|(1<<(col+1))|(1<<(col+2)),sup|(1<<col)|(1<<(col+1))|(1<<(col+2)),now,tsup); } ``` }
2.竖着放:now=1 sup= 1时候suup 0 sup 0转移来
if( ( ((1<<col)&tsup)) && ( ((1<<col) & now) ) ){ dfs(fl,col+1,suup,sup,now,tsup); }
3.不放得第一种: now = 0 sup = 1: suup = 1 sup = 1转移来(上面都放好了)
if(!((1<<col)&now) && ((1<<col)&tsup)){ dfs(fl,col+1,suup|(1<<col),sup|((1<<col)),now,tsup); }
第二种:now = 0 sup = 0: suup = 1 sup = 0转移来 (i+1行会竖着放)
if(!((1<<col)&now)&&(!((1<<col)&tsup)) ){ dfs(fl,col+1,suup|(1<<col),sup,now,tsup); }
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
int n,m;
LL dp[2][1024][1024];
void dfs(int fl,int col,int suup,int sup,int now,int tsup){
if(col == m){
//if(sup == (1<<m)-1 && suup == sup && fl == 1) cout <<" asdas "<<dp[(fl-1)%2][sup][suup]<<endl;
dp[fl%2][now][tsup] += dp[(fl-1)%2][sup][suup];
//cout << dp[fl%2][now][tsup]<<endl;
return;
}
//横着放 now 1 1 1是sup111 suup111转移而来
if(col + 3 <= m ){
if( (tsup & (1 << (col+1)) )&& ( (1 << (col+2)) & tsup) && (tsup & (1 << (col)) ) ){
if( (now & (1 << (col+1)) )&& ( (1 << (col+2)) & now ) && (now & (1 << (col)) ) )
dfs(fl,col+3,suup|(1<<col)|(1<<(col+1))|(1<<(col+2)),sup|(1<<col)|(1<<(col+1))|(1<<(col+2)),now,tsup);
}
}
//竖着放:now=1 sup= 1时候suup 0 sup 0转移来
if( ( ((1<<col)&tsup)) && ( ((1<<col) & now) ) ){ dfs(fl,col+1,suup,sup,now,tsup); }
//不放 now = 0 sup = 1: suup = 1 sup = 1转移来
if(!((1<<col)&now) && ((1<<col)&tsup)){ dfs(fl,col+1,suup|(1<<col),sup|((1<<col)),now,tsup); }
//不放 now = 0 sup = 0: suup = 1 sup = 0转移来
if(!((1<<col)&now)&&(!((1<<col)&tsup)) ){ dfs(fl,col+1,suup|(1<<col),sup,now,tsup); }
}
void init(){
for(int s1 = 0 ; s1 < (1<<m) ; s1++)
for(int s2 = 0 ;s2 < (1<<m) ; s2++)
dp[0][s1][s2] = 0;
dp[0][(1<<m)-1][(1<<m)-1] = 1;
for(int i = 1; i <= n; i++){
for(int sup = 0 ; sup < (1<<m) ; sup++){
for(int now = 0 ; now < (1<<m) ; now++){
dfs(i,0,0,0,now,sup);
}
}
for(int s1 = 0 ; s1 < (1<<m) ; s1++)
for(int s2 = 0 ;s2 < (1<<m) ; s2++)
dp[(i+1)%2][s1][s2] = 0;
}
printf("%lld\n",dp[n%2][(1<<m)-1][(1<<m)-1]);
}
int main(){
while(2==scanf("%d%d",&m,&n)){
if(n == 0&& m == 0)
break;
init();
memset(dp,0,sizeof(dp));
}
}
相关文章推荐
- ZOJ 2563 Long Dominoes(状压DP)
- ZOJ 2563 Long Dominoes(状态压缩+dp)
- zoj 2563 Long Dominoes (状态压缩dp)
- ZOJ Problem Set - 2563 Long Dominoes 【如压力dp】
- ZOJ 2563 Long Dominoes(状态压缩DP)
- ZOJ Problem Set - 2563 Long Dominoes 【状压dp】
- Long Dominoes(ZOJ 2563状压dp)
- zoj 2563 Long Dominoes
- ZOJ 2994 && HDU 1992 Tiling a Grid With Dominoes (状压DP)
- ZOJ 3471 Most Powerful (状压dp)
- 【cqbzoj】1785:残缺棋盘上放车的方案数 --状压dp --输入毁一生
- HDU 1992 Tiling a Grid With Dominoes (状压 dp)
- zoj 3777 状压dp
- ZOJ 3802 Easy 2048 Again(状压dp)
- zoj 3777 Problem Arrangement(状压dp)
- ZOJ 3471 Most Powerful (状压DP)
- zoj 3905 Cake(状压dp)
- zoj 3802 Easy 2048 Again(状压DP)
- ZOJ 1346 Comparing Your Heroes - 状压dp
- ZOJ 3802 Easy 2048 Again(状压DP+位运算)【一维状压类模板--2048】