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;
    }
  • 相关阅读:
    鹅厂女专家:用“爱折腾”实现跨界之美
    基于腾讯云的视频聊天研究
    iOS微信内存监控
    2017年数据库技术盘点
    如何做好游戏内实时语音体验
    腾讯云微计算实践:从Serverless说起,谈谈边缘计算的未来
    使用腾讯云“自定义监控”监控GPU使用率
    如何在Python中从零开始实现随机森林
    DataGridView 设置某个列为只能为数字
    Ieditor
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10960808.html
Copyright © 2011-2022 走看看