• POJ2411


    题目大意

    给定一个N*M大小的地板,要求你用1*2大小的砖块把地板铺满,问你有多少种方案?

    题解

    刚开始时看的是挑战程序设计竞赛上的关于铺砖块问题的讲解,研究一两天楞是没明白它代码是怎么写的,智商捉急,上面是用逐格进行转移的,据说神马插头DP。。。坑爹啊。。。然后果断放弃研究了。。。我们还是逐行的进行转移,这样比较好理解,方程表示为:dp[i][j]+=dp[i-1][k](能够从上一行的状态k转移到当前状态j)。我们需要枚举出符合要求的状态j和k,如果第i-1行p列没有放,那么第i行的p列肯定需要放置一个竖块,如果第i-1行p列放了,那么i行的p列可以不用放,如果第i-1行的p列和p+1列都放了,那么我们可以在第i行的p列和p+1列横着放置一个砖块。

    我们用dfs实现,那么上述三种情况可以分别表示为

    dfs(step+1,s1<<1|1,s2<<1,line); 竖放
    dfs(step+1,s1<<1,s2<<1|1,line);不放
    dfs(step+2,s1<<2|3,s2<<2|3,line);横放

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define MAXN 15
    typedef long long LL;
    LL dp[MAXN][1<<MAXN];
    int n,m;
    void dfs(int step,int s1,int s2,int line)
    {
        if(step==m)
        {
            dp[line][s1]+=dp[line-1][s2];
            return;
        }
        dfs(step+1,s1<<1|1,s2<<1,line);
        dfs(step+1,s1<<1,s2<<1|1,line);
        if(step+2<=m)
            dfs(step+2,s1<<2|3,s2<<2|3,line);
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF&&(n+m))
        {
            memset(dp,0,sizeof(dp));
            dp[0][(1<<m)-1]=1;
            for(int i=1; i<=n; i++)
                dfs(0,0,0,i);
            printf("%I64d
    ",dp[n][(1<<m)-1]);
        }
        return 0;
    }
  • 相关阅读:
    利用Python获取文件类型
    删除目录和文件
    创建目录和空文件
    读取文件内容
    sort方法
    python实例5-表格打印
    ngx.lua中遇到的小问题
    mysql 更改自动增长字段值的重新设定
    全面讲解进程池原理
    测试工程师Docker基础
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3446410.html
Copyright © 2020-2023  润新知