HDU-1992-Tiling a Grid With Dominoes-4列n行的骨牌-轮廓线DP

题意:在n*4的矩阵里,填满1*2的骨牌,有多少种可能性,我想的方向是4列n行

思路:分为三种情况。1.当前列上一行把这一行给占有了,当前行不能再放。

2.当前列上一行没有把这一行给占用,肯定可以竖这放。此时需要占有下一行。

3.当前列和下一列上一行都没把这一行给占用。可以横着放。此时不需要占有。

暴力枚举上一行对这行状态影响,然后dfs枚举出这一行对下一行的状态

dp[i][j]表示第i行对下一行产生j状态的影响的种数

dfs(s,ss,x,n)  s是上一行对当前行的影响,即当前行那些被占有了,ss是自己dfs构造这行对下一行的影响,

x是dfs处理到第几列0-3,n是在处理第几行。

最后把dp[n][0]输出就好即不对下一行产生影响

#include<bits/stdc++.h>
using namespace std;
long long dp[30][16];
void dfs(int s,int ss,int x,int n) {
///s上一行对这一行的影响,(即当前行的状态),ss当前行构造的对下一行的影响
///x正在处理第几列,n正在处理第几行 该矩阵是4列n行的
    if(x>3) {           ///全部处理完了
        dp[n+1][ss]+=dp[n][s];
        return;
    }
    if(s&(1<<x)) {      ///如果上一行已经占有这一行的这一格了直接跳过
        dfs(s,ss,x+1,n);
        return;
    }
    dfs(s,ss|(1<<x),x+1,n); ///竖着放已经确定该行没被占用。
    if(x<=2&&!(s&(1<<(x+1)))) { ///横着放,先确认下一行有没有被占用
        dfs(s,ss,x+2,n);///横着放并不会影响下一行。
    }
    return;
}
int main()
{
    memset(dp,0,sizeof dp);
    dp[0][0]=1;
    for(int i=0;i<25;i++)
        for(int j=0;j<16;j++)  {
             if(dp[i][j]) {
                dfs(j,0,0,i);
             }
        }
    int t,n;
    int kase=0;
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        printf("%d %lld\n",++kase,dp[n][0]);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值