基础算法学习---状态压缩dp

蒙德里安的梦想

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

typedef long long ll;

const int N = 12;
const int M = 1 << N;

ll f[N][M];
int n,m;
bool st[M];
vector<int> state[M];

int main(){
    while(cin >> n >> m,n || m){
        //遍历每一种摆放状态 对符合条件的状态进行赋值
        for(int i = 0;i < 1 << n;i ++){
            int cnt = 0;
            //0的个数
            for(int j = 0 ;j < n;j ++){
                //逐位检查,遇到1检查0个数
                if(i >> j & 1){
                    //为奇数
                    if(cnt & 1){
                        st[i] = false;
                        break;
                    }
                    cnt = 0;
                }else cnt ++;
            }

            if(cnt & 1) st[i] = false;
            else st[i] = true;
        }

        //对每一个i查找符合条件的i-1状态
        for(int i = 0;i < 1 << n;i ++){
            state[i].clear();
            for(int j = 0;j < 1 << n;j ++) if((i & j) == 0 && st[i | j]) state[i].push_back(j);
        }

        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(auto k : state[j])
                    f[i][j] += f[i - 1][k];

        cout << f[m][0] << endl;
    }
}
posted @ 2021-10-05 19:07  Xuuxxi  阅读(44)  评论(0)    收藏  举报