AcWing 291. 蒙德里安的梦想

2021-01-28 06:13

阅读:549

标签:false   its   mes   左移   out   cin   style   include   end   

#includeusing namespace std;
const int N = 12, M = 1  N;
int st[M];
long long f[N][M];
//用f[i][j]记录第i列第j个状态。j状态位等于1表示上一列有横放格子,本列有格子捅出来
//j是一个二进制数字     如果第1个位数字位1,表示第i-1列的第1行位一个横着放的格子的左端点
int main() {
    int n, m;
    while (cin >> n >> m && (n || m)) {
        //先预处理,所有状态是否不存在连续奇数个0
        for (int i = 0; i 1 //所有的状态是1左移n位
            st[i] = true;//假设是成立的
            int cnt = 0;//当前连续0的个数
            for (int j = 0; j )
                if (i >> j & 1) {//如果说当前这一位是1,说明上面连续0的那一段已经结束
                    if (cnt & 1) //判断上一段连续0是否为奇数个
                        st[i] = false;
                    cnt = 0;//情空
                } else cnt ++;
            if (cnt & 1) st[i] = false; // 扫完后要判断一下最后一段有多少个连续的0
        }
        memset(f, 0, sizeof f);
        //最一开始的时候,小方块什么都没有放
        f[0][0] = 1;//第一列只能0,上一列不存在,只有这一种方法
        for (int i = 1; i //枚举所有列
            for (int j = 0; j 1 //枚举所有状态
                for (int k = 0; k 1 //枚举第i-1列所有的状态
                    if ((j & k) == 0 && (st[j | k]))
                        // (j & k) == 0 表示 i 列和 i - 1列同一行不同时捅出来
                        // st[j | k] == 1 表示 在 i 列状态 j, i - 1 列状态 k 的情况下,i - 1 列无连续空行.
                        f[i][j] += f[i - 1][k];
        cout 0] //m -1列不能有横向格子的起点,所有都为0
    }
    return 0;
}

 

 

AcWing 291. 蒙德里安的梦想

标签:false   its   mes   左移   out   cin   style   include   end   

原文地址:https://www.cnblogs.com/QingyuYYYYY/p/11906299.html


评论


亲,登录后才可以留言!