zoukankan      html  css  js  c++  java
  • HDU 1400 Mondriaan's Dream

    题目链接:HDU 1400 Mondriaan's Dream

    题目大意:
    (1 imes 2)的矩形完全覆盖一个(n imes m)矩形区域,求覆盖方案数。

    题解:
    将某一行用二进制来表示是否被覆盖了,压缩信息到一个整数中,进行状态转移。

    (dp[i][j])表示前(i)行,除最后一行其他都完全覆盖,而最后一行在(j)的二进制对应位为(1)的位置竖着覆盖矩形的上半部分,(0)的位置横着覆盖矩形或竖着覆盖矩形的下半部分的情况数。

    如果(j)的二进制为(0),若竖着覆盖,则其上一行的对应位置必须为(1);若横着覆盖,则其相邻位置必须也有(0),设上一行的状态为(k),则须满足(j|k)中每段连续的(0)的个数为偶数((j|k)之后剩下的(0)位均为横着覆盖的矩形位置)且(j& k=0)(若某位是(1),则表示其是矩形上半部分,则其上一行的对应位置一定是横着覆盖的矩形或者竖着覆盖的矩形的下半部分,肯定为(0),所以按位与之后必定为(0))。

    状态转移方程为:

    [dp[i][j]=sum_{j,k符合条件}dp[i-1][k] ]

    初始(dp[0][0]=1),答案为(dp[n][0])

    #include <cstring>
    #include <iostream>
    using namespace std;
    
    long long dp[12][1 << 11];
    int n, m;
    
    bool check(int x, int y) {
        if (x & y) {
            return false;
        }
        int t = x | y, cnt = 0;
        for (int i = 0; i < m; ++i) {
            if (!(t & 1 << i)) {
                cnt++;
            } else if (cnt & 1) {
                return false;
            }
        }
        return !(cnt & 1);
    }
    
    int main() {
        while (cin >> n >> m && (n || m)) {
            if (n & 1 && m & 1) {
                cout << 0 << endl;
                continue;
            }
            memset(dp, 0, sizeof(dp));
            dp[0][0] = 1;
            for (int i = 1; i <= n; ++i) {
                for (int j = 0; j <= (1 << m) - 1; ++j) {
                    for (int k = 0; k <= (1 << m) - 1; ++k) {
                        if (check(j, k)) {
                            dp[i][j] += dp[i - 1][k];
                        }
                    }
                }
            }
            cout << dp[n][0] << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    Flex4之关于Embed外部资源的使用方法总结
    Flex tree的开发 后台数据连接
    Flex4之Tree开发
    Flex自定义组件开发
    解决AS3请求数据的“安全沙箱冲突”问题
    purMVC代码备份
    译:如何配置Red5应用程序
    关于RED5——配置文件详解
    关于socket使用Amf直接进行对象传输的
    垃圾回收机制
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/15059671.html
Copyright © 2011-2022 走看看