轮廓线DP学习笔记

不羁岁月 提交于 2021-01-10 14:57:52

轮廓线DP

不会

题目

POJ2411

题面

用1*2的骨牌覆盖N*M的棋盘的方案数

题解

代码如下:

#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;

inline int read()
{
    int f=1,x=0;
    char ch;
    do
    {
        ch=getchar();
        if(ch=='-') f=-1;
    }while(ch<'0'||ch>'9');
    do
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }while(ch>='0'&&ch<='9');
    return f*x;
}

int n,m;
int cur;
long long dp[2][1<<17];

inline void calc(int x,int y)
{
    if((y&(1<<(m)))) dp[cur][y^(1<<m)]+=dp[cur^1][x];
}

int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        if(n==0&&m==0) return 0;
        if(n<m) swap(n,m);
        memset(dp,0,sizeof(dp));
        cur=0;
        dp[0][(1<<m)-1]=1;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                cur^=1;
                memset(dp[cur],0,sizeof(dp[cur]));
                for(int k=0;k<=(1<<m)-1;k++)
                {
                    calc(k,k<<1);
                    if(i&&!(k&(1<<m-1))) calc(k,(k<<1)^(1<<m)^1);
                    if(j&&!(k&1)) calc(k,(k<<1)^3);
                }
            }
        }
        cout<<dp[cur][(1<<m)-1]<<endl;
    } 
} 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!