• 状态压缩DP 初探


    状态压缩DP 初探

    +++

    1.蒙德里安的梦想

    求把NM的棋盘分割成若干个12的的长方形,有多少种方案。

    例如当N=2,M=4时,共有5种方案。当N=2,M=3时,共有3种方案。

    如下图所示:

    2411_1.jpg

    输入格式

    输入包含多组测试用例。

    每组测试用例占一行,包含两个整数N和M。

    当输入用例N=0,M=0时,表示输入终止,且该用例无需处理。

    输出格式

    每个测试用例输出一个结果,每个结果占一行。

    数据范围

    1≤N,M≤111≤N,M≤11

    输入样例:

    1 2
    1 3
    1 4
    2 2
    2 3
    2 4
    2 11
    4 11
    0 0
    

    输出样例:

    1
    0
    1
    2
    3
    5
    144
    51205
    
    题解:

    我们可以分析横着放方块的方案数,即为答案数。

    按列分析,如果此列想要放置一个横向方块,那么i - 1列就不可以捅到第i列(即此位置无位于i - 1列和i列的横向方块),我们可以用j & k来判断此情况,其中j是枚举第i列的状态,k是枚举i - 1列的状态。

    其次,为了可以让空位置可以让竖向方块刚好填满,那么第i列就不可以有连续奇数个0,用j | k来判断此情况。

    最后做一遍dp即可。

    状态表示:f[i] [j] 表示第i列状态是j的方案数,j则表示的是i - 1列捅到第i列的状态(一个二进制数)。

    状态属性:max,最大方案数

    AC代码:
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    const int N = 12, M = 1 << N;
    
    long long f[N][M];
    int n, m;
    bool st[M];
    
    int main()
    {
        while (cin >> n >> m, n || m)
        {
            //预处理st数组
            for (int i = 0; i < 1 << n; i ++ )
            {
                st[i] = true;
                
                int cnt = 0;
                for (int j = 0; j < n; j ++ )
                    if(i >> j & 1)
                    {
                        if(cnt & 1) st[i] = false;
                        cnt = 0;
                    }
                    else cnt ++ ;
                
                if(cnt & 1) st[i] = false;
            }
            
            memset(f, 0, sizeof f);
            f[0][0] = 1;
            
            for (int i = 1; i <= m; i ++ )
                for (int j = 0; j < 1 << n; j ++ )
                    for (int k = 0; k < 1 << n; k ++ )
                        if((j & k) == 0 && st[j | k])
                            f[i][j] += f[i - 1][k];
            
            cout << f[m][0] << endl;
        }
        
        return 0;
    }
    
  • 相关阅读:
    收集起来先
    asp .net 页面回车触发button 按钮事件
    关于SQL 数据库表中的聚集索引和非聚集索引等
    WinForm换肤操作(用IrisSkin2.dll)
    生成Word文档的相关操作
    API自动化测试测试数据集
    API文档实践
    使用eolinker对API测试的响应结果进行断言
    API自动化定时测试
    接口测试之对数据进行RSA加解密
  • 原文地址:https://www.cnblogs.com/scl0725/p/13909780.html
Copyright © 2020-2023  润新知