zoukankan      html  css  js  c++  java
  • 状压dp(不知道哪里的题目)

    这是一道流传至今的状压dp,好像很多人都不知道他的源头在哪里,但是他作为状压dp的入门却是口口相传,他就是一个经典的贴瓷砖问题

    题目:有一个N*M(N<=5,M<=1000)的棋盘,现在有1*2及2*1的小木块无数个,要盖满整个棋盘,有多少种方式?答案对某个数取模。

    思路:我们可以看到有一维很小,小到可以状压(滑稽),我们当然是对一维进行状压,一维进行枚举,dfs(i,j,state,nxt)代表第i列,第j行,这一行想填成的状态为state,以及填成state时下一列的状态为nxt

    然后我们就可以愉快的转移了(反正大体的思路了就是这样,我也不知道我写的对不对)

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int MOD=1e9+7;
    int n,m;
    
    LL dp[1005][35];
    void dfs(int i,int j,int state,int nxt)
    {
        if(j==n){
            dp[i+1][nxt]+=dp[i][state];
            dp[i+1][nxt]%=MOD;
            return ;
        }
        if(((1<<j)&state)==1)dfs(i,j+1,state,nxt);
        if(((1<<j)&state)==0)dfs(i,j+1,state,nxt|(1<<j));
        if(j+1<n&&(((1<<j)&state)==0)&&(((1<<(j+1)&state)==0)))
            dfs(i,j+2,state,nxt);
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            memset(dp,0,sizeof(dp));
            dp[1][0]=1;
            for(int i=1;i<=m;i++){
                for(int j=0;j<=(1<<n);j++){
                    dfs(i,0,j,0);
                }
            }
            printf("%lld
    ",dp[m+1][0]);
        }
        return 0;
    }
  • 相关阅读:
    微信小程序的scheme码
    微信小程序的简单总结(uni-app)
    ES7-ES11新特性
    Promise 总结
    uni-app创建项目及使用 vant-weapp
    vscode 插件整理
    el-upload 组件总结
    从输入URL到页面显示过程中发生了什么
    实验 1:Mininet 源码安装和可视化拓扑工具
    2020软件工程第一次作业
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/9696394.html
Copyright © 2011-2022 走看看