AcWing 291. 蒙德里安的梦想
标签: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
评论