POJ2411 轮廓线动态规划典型例题

在做状态压缩时看到了这道题:

总结一下:
状态压缩特点:
某一维或几维非常小
最优性原理,无后效性
(遍历的点的具体顺序对以后的决策是没有影响的)

基于连通性的状态压缩详解:http://www.doc88.com/p-9009338580746.html

题意:给出一个n*m的矩形,然后用1*2大小的多米若骨牌去填充n*m的这个矩形,问有多少种填充方法。

分析参考:http://blog.csdn.net/u013480600/article/details/19499899

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 15;
long long d[2][1<<maxn];
int n,m,cur;
void update(int a,int b)//a是包含m位1进制数的老状态,b是包含m+1位1进制数的新状态
{
    if(b&(1<<m)) d[cur][b^(1<<m)] += d[1-cur][a];//只有新轮廓线首位为1时才更新
}
int main()
{
    while( scanf("%d%d",&n,&m)==2&&n&&m )
    {
        if(m>n)swap(n,m);
        memset(d,0,sizeof(d));
        cur=0;
        d[cur][(1<<m)-1]=1;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                cur ^=1;
                memset(d[cur],0,sizeof(d[cur]));
                for(int k=0;k<(1<<m);k++)//k的二进制形式表示前一个格子的轮廓线状态
                {
                    update(k,k<<1);//当前格不放,直接k左移一位就表示带m+1位的新轮廓线的状态
                    if(i && !(k&(1<<(m-1)) )) update(k,(k<<1)^(1<<m)^1);//上放,要求轮廓线首为0
                    if(j && (!(k&1)) ) update(k,(k<<1)^3);//左放,要求轮廓线尾0,首1
                }
            }

        printf("%I64d\n",d[cur][(1<<m)-1]);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值