zoukankan      html  css  js  c++  java
  • hihocoder1048 : 状态压缩·二

          题目链接: http://hihocoder.com/problemset/problem/1048?sid=1171317

      1.思路

        状压DP经典题目,对于横着放的矩形,我们将两个格子都标记为1;对于竖着放的矩形,我们将(i-1,j) 标记为0, 将(i, j) 标记为1;

      2.代码

    /***********************************************************
       
            FileName:hiho1048.cpp
              Author:zQ
               Email: zq216991@foxmail.com
              Create:2017-09-13 16:17:38
        Descripttion:状压DP
       
    *************************************************************/
    #define debug printf("%s: %d
    ", __FUNCTION__, __LINE__);
    // http://blog.csdn.net/hopeztm/article/details/7841917
    
    #include <bits/stdc++.h>
    using namespace std;
    const int mod = 1e9+7;
    const int N = 1005;
    typedef long long ll;
    
    ll dp[N][N];
    int n, m;
    
    // 预先处理第一行的状态
    int testFirstLine(int s) {
        int i = 0;
        while(i < m) {
            if(s&(1<<i)) {
                if(i==m-1 || (s&(1<<(i+1)))==0) {
                    return 0;
                }
                i += 2;
            }
            else {
                ++ i;
            }
        }
        return 1;
    }
    
    // 在位置(i, j) 如果我们选择横着贴砖,那么将(i, j), (i, j+1)都填写成1, 如果竖着贴砖,我们将(i,j)填写成0, 将(i+1, j)填写成1.
    
    bool ok(int a, int b) {
        int i = 0;
        while(i < m) {
            if((a&(1<<i)) == 0) {
                if((b&(1<<i)) == 0) {
                    return false;
                }
                ++ i;
            }
            else {
                if((b&(1<<i)) ==0) {    // 竖着铺
                    ++ i;
                }
                // 横着铺
                else if(i != m-1 && (a&(1<<(i+1))) && (b&(1<<(i+1))) ) {
                    i += 2;
                }
                else {
                    return false;
                }
            }
        } 
        return true;
    }
    
    int main() {
        cin >> n >> m;
        int x = (1<<m);
        for(int j = 0; j < x; ++ j) {
            dp[1][j] = testFirstLine(j);
        }
    
        for(int i = 2; i <= n; ++ i) {
            for(int j = 0; j < x; ++ j) {
                for(int k = 0; k < x; ++ k) {
                    if(ok(j, k)) {
                        dp[i][j] += dp[i-1][k];
                        dp[i][j] %= (ll)mod;
                    }
                }
            }
        }
        printf("%lld
    ", dp[n][x-1]);
        return 0;
    }
    

      

  • 相关阅读:
    Centos 7 运行出错:cannot find a valid basecrl for repo:base/7/x86_64
    nc 使用
    linux uniq去重,awk输出(可用于爆破字典优化)
    关于fixedsys字体 FSEX300.ttf FSEX300-L.ttf FSEX301-L2.ttf
    MyAtoi
    viplugin eclipse
    资源获取即初始化RAII
    阈值分割技术
    图像类型转换
    形态学
  • 原文地址:https://www.cnblogs.com/topk/p/7516630.html
Copyright © 2011-2022 走看看