• 牛客 小乐乐搭积木


    链接:https://ac.nowcoder.com/acm/contest/301/B
    来源:牛客网

    题目描述

    小乐乐想要给自己搭建一个积木城堡。
    积木城堡我们假设为n*m的平面矩形。
    小乐乐现在手里有1*2,2*1两种地砖。
    小乐乐想知道自己有多少种组合方案。

    输入描述:

    第一行输入整数n,m。(1<=n,m<=10)

    输出描述:

    输出组合方案数。
    示例1

    输入

    复制
    2 3

    输出

    复制
    3

    说明

    示例2

    输入

    复制
    1 3

    输出

    复制
    0
    示例3

    输入

    复制
    2 5

    输出

    复制
    8

    状压dp
    但是之前写铺砖的时候写的很复杂,做这道题的时候看了一下别人的博客用的搜索来找转移状态,学到了。

    状压dp利用二进制来表示状态,适用于 n, m 较小的情况(一般都小于等于10)。
    在本题中用二进制 1 表示这块方格被砖块覆盖了(不管他是被从哪里过来的砖覆盖的,从上面,下面还是左面都是一样的)用 0 来表示没有被覆盖。
    dp[i][j]表示第i列对下一列的影响为j。 j需要被二进制展开,展开后成 (1/0)*2^(m-1),(1/0)*2^(m-2),....(1/0)*2^0
    假设 2^(m-1) 的系数为 1 ,这意味着第i行的第m块方块是被一个横着放的1*2砖块覆盖了,所以才对(i+1)行的第m块方块有影响

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 long long dp[11][1050];
     7 int to[10050][2];
     8 int num = 0;
     9 int n, m;
    10 void dfs(int l,int pre, int now){
    11     if(l>m)
    12         return ;
    13     if(l==m){
    14         to[++num][0] = pre;
    15         to[num][1] = now;
    16         return ;
    17     }
    18     dfs(l+1,pre<<1,now<<1|1);
    19     dfs(l+2,pre<<2,now<<2);
    20     dfs(l+1,pre<<1|1,now<<1);
    21 }
    22 int main(){
    23     scanf("%d%d",&n,&m);
    24     memset(dp,0,sizeof(dp));
    25     dp[0][0] = 1;
    26     if(n>m)swap(n,m);
    27     dfs(0,0,0);
    28     for(int i=1;i<=n;i++){
    29         for(int j=1;j<=num;j++){
    30             dp[i][to[j][1]] += dp[i-1][to[j][0]];
    31         }
    32     }
    33     printf("%lld
    ",dp[n][0]);
    34     return 0;
    35 }
    View Code
  • 相关阅读:
    luogu_1414 又是毕业季II
    luogu_1372 又是毕业季I
    luogu_1313 计算系数
    luogu_1134 阶乘问题
    luogu_1514 引水入城
    luogu_1120 小木棍
    文件操作
    快速排序
    c oth
    ANSI C与C89、C99、C11区别差异
  • 原文地址:https://www.cnblogs.com/kongbb/p/10066443.html
Copyright © 2020-2023  润新知