• Mondriaan's Dream 题解(棋盘状压问题)


    题目链接

    题目大意

    现在有一个 n×m 的方格棋盘,和无限的 1×2 的骨牌。

    问有多少种方法可以用骨牌铺满棋盘。1 ≤ n,m ≤ 11

    题目思路

    这种算是状压dp的模板题目

    主要是思考上一行和这一行的转移即可

    需要两个连续的空位,并且上一行的这两个位置也得已经被覆盖。
    如果竖着:
    (a) 上一行对应的位置是空的,我们把那个空填上。

    (b) 上一行对应的位置是被覆盖的,那么我们把这一行的位置设为空,表示下一行的对应位置必须竖放,填上这块空白。

    运行dfs预处理所有状态即可

    代码

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define se second
    #define debug cout<<"I AM HERE"<<endl;
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+5,inf=0x3f3f3f3f,mod=1e9+7;
    const double eps=1e-6;
    int n,m;
    int tot=0;
    int from[maxn],to[maxn];
    ll dp[15][1<<12];
    void dfs(int d,int pre,int now){
        if(d>m) return ;
        if(d==m){
            ++tot;
            from[tot]=pre;
            to[tot]=now;
        }
        dfs(d+2,pre<<2|3,now<<2|3);
        dfs(d+1,pre<<1,now<<1|1);
        dfs(d+1,pre<<1|1,now<<1);
    }
    signed main(){
        while(scanf("%d%d",&n,&m)!=-1&&(n+m)){
            memset(dp,0,sizeof(dp));
            tot=0;
            dfs(0,0,0);
            dp[0][(1<<m)-1]=1;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=tot;j++){
                    dp[i][to[j]]+=dp[i-1][from[j]];
                }
            }
            printf("%lld
    ",dp[n][(1<<m)-1]);
        }
        return 0;
    }
    
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    机器学习(ML)二之损失函数
    机器学习包pip清华镜像源安装方法
    机器学习(ML)一之 Linear Regression
    linux安装glibc-2.14后字符集出问题
    HBase单机环境搭建
    MySQL基础笔记(六) 存储过程与函数
    MySQL基础笔记(五) 视图
    MySQL基础笔记(四) 索引
    MySQL基础笔记(三) 复杂查询
    MySQL基础笔记(二) 完整性约束
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/15177814.html
Copyright © 2020-2023  润新知