AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 应用
  • 更多
    • 题解
    • 分享
    • 商店
    • 问答
    • 吐槽
  • App
  • 登录/注册

AcWing 291. 291. 蒙德里安的梦想 (状态压缩dp 模板 )    原题链接    中等

作者: 作者的头像   卷卷死他们 ,  2023-03-19 16:53:19 ,  所有人可见 ,  阅读 31


0


推荐题解
797b05b0037f980fc929371f7c27a0b.jpg

#include <iostream>
#include <cstring>

using namespace std;

const int N = 12, M = 1 << N; //M: 一共有多少种状态

long long f[N][M]; //可能爆int,f[i][j]:摆好前i-1 列,第i-1 列状态是j,第i-1 列的横放格子延伸到第i 列。
bool vi[M]; //判断每一列哪些状态合法,要满足两个条件:i-2列与第i列不会冲突; 连续空格数量为偶数
int n, m;

int main()
{
    while (cin >> n >> m, n || m)
    {
        //枚举每一列的所有状态,找合法的状态
        for (int i = 0; i < 1 << n; i++) //状态数量为 2^n, n位二进制
        {
            int cnt = 0; //记录连续0 (空格)的数量
            vi[i] = true; //假设这个状态合法,找矛盾
            for (int j = 0; j < n; j++) //n 位二进制,从低位看
            {
                if (i >> j & 1) //若这一位是1
                {
                    if (cnt & 1) //若前面连续0的数量是奇数
                        vi[i] = false; //状态不合法
                    cnt = 0; //清空前面记录的连续0
                }
                else //这一位是0
                    cnt++;
            }

            if (cnt & 1) 
                vi[i] = false;
            /*
                判断开头处的连续0是否为奇数,我们还要看前导0是不是偶数
                如0001,要枚举完。
                我们右移的时候移的是n 位,可能最高位是0, 不是1.
            */
        }

        //多次输入,初始化
        memset(f, 0, sizeof f);
        f[0][0] = 1; //初始化

        //dp
        for (int i = 1; i <= m; i++) //从第一列开始
            for (int j = 0; j < 1 << n; j++) //枚举第 i 列的所有状态
                for (int k = 0; k < 1 << n; k++) //枚举第 i-1列的状态,第i-1 列状态也是第 i 列的伸出状态
                    if ((j & k) == 0 && vi[j | k])
                        f[i][j] += f[i-1][k]; 

        /*
             j&k == 0,i列与i-1列之间的状态没有冲突;
             j|k:两者有一个为1都为1。i-1的状态k 如何,i-1列会伸展到第i列,且已经保证了不冲突,所以 j&k 就是
                    第i列最终的状态,vi[j|k] = true, 表明状态合法
             f[i][j] += f[i-1][k] : 加上前一列,且第i-1列状态就是k 的方案数量
        */

        cout << f[m][0] << endl; //前m-1列已经摆好了,且第m 列没有伸出。即0~m-1列已经摆满了
    }

    return 0;
}

0 评论

你确定删除吗?
1024
x

© 2018-2023 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息