Mondriaan's Dream POJ

编程入门 行业动态 更新时间:2024-10-23 14:24:12

<a href=https://www.elefans.com/category/jswz/34/1690258.html style=Mondriaan's Dream POJ"/>

Mondriaan's Dream POJ

一、内容

题意:给定n,m, 将1x2的小方格放入其中,求有多少种方法。

二、思路

  • F【i】【j】代表对于i列 该列横向放小方块的状态为j, 里面存放的是方案数。j代表二进制状态1代表该行放了小方块
  • 我们先设i行的状态为j,i-1行的状态为k。
  • 由于我们枚举了所有横着放小方块的状态,那么剩下的位置只能竖着放小方块,所以我们要求连续0的位置必须是偶数,因为竖着放小方块占2行,所以必须空出2个位置出来。所以 j | k 这个状态下连续0必须是偶数。
  • 还有就是与i-1列的状态不能冲突,因为若i-1列的某行已经放了一个小方块,那么i列的这行就不能放了,所以 (j & k) == 0

三、代码

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 12;
ll f[N][1 << N];
bool st[1 << N];
int n, m;
int main() {while (scanf("%d%d", &n, &m), n){memset(f, 0, sizeof(f));//每次统计下状态中奇数0的情况 连续0为奇就是falsefor (int i = 0; i < 1 << n; i++) {int cnt = 0;st[i] = true; //代表初始化是偶数个0 for (int j = 0; j < n; j++) {if (i & (1 << j)) {//代表遇到一个1if (cnt & 1) break;cnt = 0; } else {cnt++;}}if (cnt & 1) st[i] = false;}f[0][0] = 1; //初始状态 //枚举i列状态 和i-1列状态  列是0~m-1 for (int i = 1; i <= m; i++) {for (int j = 0; j < 1 << n; j++) {for (int k = 0; k < 1 << n; k++) {//前一个状态表示不冲突  后一个表示连续0为偶数if ((j & k) == 0 && st[j | k]) {f[i][j] += f[i - 1][k];}}} }	//最后输出答案0~m-1 列已经拍好 那么m列就是000...00这个状态printf("%lld\n", f[m][0]); }return 0;
} 

更多推荐

Mondriaan's Dream POJ

本文发布于:2024-02-13 22:25:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1760967.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Mondriaan   Dream   POJ

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!