http://acm.pku.edu.cn/JudgeOnline/problem?id=2411

    挺简单的一道题,由于自己很少做这类型的题目,做出来还是挺有感觉的。

    每一个木块只有两种摆放方式,用0 , 1表示,0表示横放,1表示竖放,所以每一行,必须要有连续偶数个0,而且最后一行不能有1。若这一列对应的上一行有1,则这一列不能为1,但是计算的时候要把这一列看成1,若对应可放,则可以加上所对应的值,由于每一个状态可以对应多个可行状态,所以要递推累加。最有结果为dp[h][0]。

代码
1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4
5  using namespace std;
6
7 typedef long long LL;
8 const int maxn = (1 << 12);
9
10 LL h , w , dp[12][maxn];
11
12 bool judge(LL s)
13 {
14 LL cnt = 0;
15 for(LL i=0; i < w; i++)
16 {
17 LL t = s & 1;
18 if(t)
19 {
20 if(cnt & 1)
21 return false;
22 else
23 cnt = 0;
24 } else
25 cnt ++;
26 s >>= 1;
27 }
28 if(cnt & 1)
29 return false;
30 return true;
31 }
32
33 int main()
34 {
35 while(~scanf("%lld %lld", &h, &w))
36 {
37 if(h == 0 && w == 0)
38 break;
39 memset(dp , 0 , sizeof(dp));
40 for(LL i=0; i < (1 << w); i++)
41 {
42 if(judge(i))
43 {
44 dp[1][i] = 1;
45 }
46 }
47 for(LL i=2; i <= h; i++)
48 {
49 for(LL j=0; j < (1 << w); j++)
50 {
51 for(LL k=0; k < (1 << w); k++)
52 {
53 LL t = j & k;
54 if(t)
55 continue;
56 t = j | k;
57 if(judge(t))
58 {
59 dp[i][j] += dp[i - 1][k];
60 }
61 }
62 }
63 }
64 printf("%lld\n", dp[h][0]);
65 }
66 return 0;
67 }
68

 

posted on 2010-06-12 12:52  xIao.wU 思维磁场  阅读(769)  评论(0编辑  收藏  举报