[poj2411]Mondriaan's Dream

传送门

题目描述: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 }

本题完结

感觉更适合初学状压做。。。

转载于:https://www.cnblogs.com/rikurika/p/poj2411.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值