zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    QMainWindow透明背景
    在Xcode中产看QString的数据
    使用QtConcurrent在线程池中执行网络操作
    QThread和QObject的调用方法总结
    策略模式 C++实现
    【转】单元测试要做多细?
    Mac系统添加QQ邮箱帐号提示无法验证
    Qt半透明对话框
    SVD的几何意义,以及在去噪,推荐系统中的应用
    BP神经网络原理及python实现
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/11906299.html
Copyright © 2011-2022 走看看