[poj2411]Mondriaan's Dream
阿新 • • 發佈:2019-02-11
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)); 39if(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