POJ 2411 状压DP&&DFS

来源:互联网 发布:汽车报价大全软件下载 编辑:程序博客网 时间:2024/05/16 15:08

用1*2 的矩形通过组合拼成大矩形,求拼成指定的大矩形有几种拼法。

状压DP+DFS


用2进制的01表示不放还是放第i行只和i-1行有关枚举i-1行的每个状态,推出由此状态能达到的i行状态如果i-1行的出发状态某处未放,必然要在i行放一个竖的方块,所以我对上一行状态按位取反之后的状态就是放置了竖方块的状态。然后用搜索扫一道在i行放横着的方块的所有可能,并且把这些状态累加上i-1的出发状态的方法数,如果该方法数为0,直接continue。
#include "stdio.h"#include "string.h"int b[]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192};int n,m;__int64 temp,dp[12][1<<11];void dfs(int i,int status,int k) // i:当前行   status:状压值    k:第k个位置{    if (k==m) {dp[i][status]+=temp; return ;}     dfs(i,status,k+1);    if (k<=m-2 && !(status&b[k]) && !(status&b[k+1]) ) // 放横条可以放下        dfs(i,status|b[k]|b[k+1],k+2); }int main(){    int aim,i,j;    while (scanf("%d%d",&n,&m)!=EOF)    {        if (n<=0 && m<=0) break;        memset(dp,0,sizeof(dp));        temp=1;        dfs(1,0,0);        aim=(1<<m)-1;        for (i=2;i<=n;i++)            for (j=0;j<=aim;j++)            {                if (dp[i-1][j]) temp=dp[i-1][j]; else continue; //上一行j方案存在可行解                dfs(i,(~j)&aim,0); // 对上一行的方案取反,空的位置直接插入纵向矩形,            }        printf("%I64d\n",dp[n][aim]);    }    return 0;}





0 0
原创粉丝点击