acwing 291. 蒙德里安的梦想

求把N*M的棋盘分割成若干个1*2的的长方形,有多少种方案。

j表示 n 位二进制数 1 表示有“突出”

f[i][j]表示当前状态

f[i-1][k]是上一行的状态

if ((j&k)==0&&st[j|k]) f[i][j]+=f[i-1][k];

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 12, M = 1 << N;
int n, m;
ll f[N][M];
bool st[M];
int main()
{
    while (cin>>n>>m,n||m)
    {
        for (int i=0;i<1<<n;i++)
        {
            int cnt=0;
            st[i]=true;
            for (int j=0;j<n;j++)
                if (i>>j&1)
                {
                    if (cnt&1)st[i]=false;
                    cnt=0;
                }
                else cnt++ ;
            if (cnt&1)st[i]=false;
        }
        memset(f,0,sizeof(f));
        f[0][0]=1;
        for (int i=1;i<=m;i++)
            for (int j=0;j<1<<n;j++)
                for (int k=0;k<1<<n;k++)
                    if ((j&k)==0&&st[j|k])
                        f[i][j]+=f[i-1][k];
        cout<<f[m][0]<<endl;
    }
    return 0;
}

 

posted @ 2020-12-26 12:26  君与  阅读(85)  评论(0编辑  收藏  举报