ZOJ 2563 Long Dominoes(状压DP)题解

Posted kirinsb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n", dp[n][fac[m] - 1]);
    
    return 0;

 

以上是关于ZOJ 2563 Long Dominoes(状压DP)题解的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ 3777-Problem Arrangement(状压DP)

zoj 3471 状压DP

zoj 3777 状压dp || 二分+搜索

zoj 3471 Most Powerful 状压dp

zoj 3471 Most Powerful (有向图)最大生成树 状压dp

ZOJ2845 旅游规划