1. 程式人生 > >[poj2411]Mondriaan's Dream

[poj2411]Mondriaan's Dream

clas clu bool sca != cst continue col lld

傳送門

題目描述:1*2的骨牌鋪滿n*m的矩形的方案數

經典狀壓dp水題

 1 #include<cstdio>
 2 #include<cstring>
 3 typedef long long lint;
 4 int swap(int &a,int &b){int t=a;a=b;b=t;}
 5 lint dp[13][1<<11];//已經鋪滿了幾行,及凸出來一行的狀態 
 6 int a,b;
 7 
 8 
 9 bool check(int s)
10 {
11     int bef=0;
12     for
(int i=0;i<b;i++) 13 { 14 if(s&(1<<i)) 15 { 16 if(bef%2) return 0; 17 }else bef++; 18 if(i==b-1&&bef%2) return 0; 19 } 20 return 1; 21 } 22 23 int main() 24 { 25 while(scanf("%d%d",&a,&b)!=EOF) 26 {
27 if(a==0&&b==0) return 0; 28 if(a==0||b==0) 29 { 30 puts("0"); 31 continue; 32 } 33 if((a%2)&&(b%2)) 34 { 35 puts("0"); 36 continue; 37 } 38 memset(dp,0,sizeof(dp)); 39
if(a>b) swap(a,b); 40 int ful=(1<<b)-1; 41 dp[0][0]=1; 42 for(int i=0;i<=a;i++) 43 { 44 for(int j=0;j<=a;j++) 45 { 46 dp[j+1][0]+=dp[j][ful]; 47 dp[j][ful]=0; 48 } 49 for(int s1=0;s1<ful;s1++) 50 { 51 for(int s2=0;s2<=ful;s2++) 52 { 53 if(s1&s2) continue; 54 if(check(s1|s2)) dp[i+1][s2]+=dp[i][s1];//檢驗能否通過s1鋪一行之後下一行的凸出狀態變為s2 55 } 56 } 57 for(int j=0;j<=a;j++) 58 { 59 dp[j+1][0]+=dp[j][ful]; 60 dp[j][ful]=0; 61 } 62 } 63 printf("%lld\n",dp[a][0]); 64 } 65 }

本題完結

感覺更適合初學狀壓做。。。

[poj2411]Mondriaan's Dream