pku 2411 Mondriaan's Dream 状态压缩DP

简要题意:
给出一个n*m的矩形,要求用1*2的矩形拼出来(可以旋转),问总共有多少种拼法。

题解:
将第i行进行状态压缩表示
(0,0,0,0..0) 0代表向下没有插头,1代表向下有插头
然后向下一行转移方法就是
如果当前列有插头,则取消掉插头;
如果当前列没有插头:
1、如果下一列也没有插头,可以水平放一个小矩形或者竖直放两个小矩形,插头状态不变
2、如果下一列有插头,则竖直放一个小矩形,添加两个向下的插头
注意要用long long
代码:
 1 # include <iostream>
 2 # include <cstring>
 3 # define getbit(c,pos) (((c)&(1<<(pos)))>0)
 4 using namespace std;
 5 void add(int code,int now,int m,long long dp[],int num)
 6 {
 7    if(now==m)
 8       dp[code]+=num;
 9    else
10    {
11        switch(getbit(code,now))
12        {
13           case 1:
14                add(code-(1<<now),now+1,m,dp,num);
15                break;
16           case 0:
17                if(now!=m-1&&!getbit(code,now+1))
18                      add(code,now+2,m,dp,num);
19                add(code+(1<<now),now+1,m,dp,num);
20                break;
21        };
22    }
23 }
24 int main()
25 {
26     int n,m;
27     while(true)
28     {
29        cin>>n>>m;
30        if(!n&&!m) break;
31        long long dp[15][2048];
32        memset(dp,0,sizeof(dp));
33        dp[0][0]=1;
34        for(int i=0;i<n;i++)
35           for(int j=0;j<(1<<m);j++)
36             if(dp[i][j])
37                  add(j,0,m,dp[i+1],dp[i][j]);
38        cout<<dp[n][0]<<endl;
39     }
40     return 0;
41 }
42 



posted on 2010-11-25 19:18 yzhw 阅读(274) 评论(0)  编辑 收藏 引用 所属分类: DP


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜