zoukankan      html  css  js  c++  java
  • ZOJ 2563 Long Dominoes(状压DP)题解

    题意:n*m的格子,用1 * 3的矩形正好填满它,矩形不能重叠,问有几种填法

    思路:poj2411进阶版。我们可以知道,当连续两行的摆法确定,那么接下来的一行也确定。当第一行还有空时,这时第三行必须要用3 * 1的去填;当第一行没有空第二行有空时,第三行必须不填;当第一行有空第二行没空,这种不能存在;当前两行没空时,我最多就是填1 * 3的方块。

    代码:

    #include<set>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 11 + 5;
    const int M = maxn * 30;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e4 + 7;
    ll dp[31][1 << maxn];
    int fac[maxn];
    int vis[maxn];
    int n, m;
    int prest;
    //0:都是空的 1:上一个非空 2:都非空
    int getSt(){
        int ret = 0;
        for(int i = m - 1; i >= 0; i--)
            ret = ret * 3 + vis[i];
        return ret;
    }
    void dfs(int i, int j){
        if(j >= m){
            int st = getSt();
            dp[i][st] += dp[i - 1][prest];
            return;
        }
        int p = prest / fac[j] % 3;
        if(p == 0){
            vis[j] = 2;
            dfs(i, j + 1);
        }
        else if(p == 1){
            vis[j] = 0;
            dfs(i, j + 1);
        }
        else{
            if(j >= 2 && vis[j - 1] == 1 && vis[j - 2] == 1){
                vis[j] = vis[j - 1] = vis[j - 2] = 2;
                dfs(i, j + 1);
                vis[j] = vis[j - 1] = vis[j - 2] = 1;
            }
            vis[j] = 1;
            dfs(i, j + 1);
        }
    }
    int main(){
        fac[0] = 1;
        for(int i = 1; i <= 10; i++) fac[i] = fac[i - 1] * 3;
        while(~scanf("%d%d", &m, &n) && n + m){
            memset(dp, 0, sizeof(dp));
            dp[0][fac[m] - 1] = 1;
            for(int i = 1; i <= n; i++){
                for(int j = 0; j < fac[m]; j++){
                    if(dp[i - 1][j] == 0) continue;
                    memset(vis, 0, sizeof(vis));
                    prest = j;
                    dfs(i, 0);
                }
            }
            printf("%lld
    ", dp[n][fac[m] - 1]);
        }
        return 0;
    }
  • 相关阅读:
    线段树专辑—— pku 1436 Horizontally Visible Segments
    线段树专辑——pku 3667 Hotel
    线段树专辑——hdu 1540 Tunnel Warfare
    线段树专辑—— hdu 1828 Picture
    线段树专辑—— hdu 1542 Atlantis
    线段树专辑 —— pku 2482 Stars in Your Window
    线段树专辑 —— pku 3225 Help with Intervals
    线段树专辑—— hdu 1255 覆盖的面积
    线段树专辑—— hdu 3016 Man Down
    Ajax跨域访问
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10960808.html
Copyright © 2011-2022 走看看