POJ 2411 Mondriaan's Dream

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

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

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

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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

 

转载于:https://www.cnblogs.com/xiao_wu/archive/2010/06/12/1756967.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值