AcWing 291. 蒙德里安的梦想
Posted qingyuyyyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 291. 蒙德里安的梦想相关的知识,希望对你有一定的参考价值。
#include<bits/stdc++.h> using 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 << n; i ++) { //所有的状态是1左移n位 st[i] = true;//假设是成立的 int cnt = 0;//当前连续0的个数 for (int j = 0; j < n; 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 <= m; i ++)//枚举所有列 for (int j = 0; j < 1 << n; j ++)//枚举所有状态 for (int k = 0; k < 1 << n; k ++)//枚举第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 << f[m][0] << endl;//m -1列不能有横向格子的起点,所有都为0 } return 0; }
以上是关于AcWing 291. 蒙德里安的梦想的主要内容,如果未能解决你的问题,请参考以下文章