蒙德里安的猜想

思路:

(1)注意到横行锁定后,纵行存放方式已经确定,所以只用考虑横行存放。

(2)f[i][j]表示第i列的j类横行存放方式,其中1<=i<=m;0<=j<1<

(3)逐列枚举,对于每列,逐状态枚举,对于每种状态,都是由上一状态演化而来,设为k,枚举每种上一状态,首先不能同时在同行放,即需要(j&k) ==0,其次在第i列中不能有连续奇数个未存放的行,即j|k需要满足条件,如果均满足条件,则f[i][j] 可以由f[i][k]演化而来,即f[i][j]+=f[i][k];

(4)预处理:提前预处理st[]来判定某状态是否合法(是否有连续奇数个0);枚举0~1<

代码:

#include

using namespace std;

const int N = 12,M = 1 << N;
long long f[N][M],st[M];
int n,m;


int main()
{
    while(cin >> n >> m, n|| m)
    {
        memset(f,0,sizeof f);
        
        for(int i = 0;i < 1<> j & 1)
                {
                    if(cnt & 1) st[i]  = 0;
                    cnt = 0;
                }
                else
                    cnt ++;
            }
            
            if(cnt & 1) st[i] = 0;
        }

        f[0][0] = 1;
        for(int i = 1;i <= m;i ++)
        {
            for(int j = 0;j < 1<

你可能感兴趣的:(算法)