【HDU2606】Renovation Problem(递推)

本文探讨了一种算法问题,即使用1*1,2*2,3*3,4*4大小的瓷砖铺设4*N区域的方法数量。通过动态规划策略,文章详细解释了如何计算不同组合方式的总数,并提供了一段C++代码实现。

题目链接

Renovation Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 754    Accepted Submission(s): 263


 

Problem Description

The New Year’s Day is comming ! Every family want to make theiir house looks more beautiful , so does Teddy’s . To make his own house looks different from other's , he went to the shop to buy four kinds of tiles . each kind of tiles has different size : 1*1 , 2*2 , 3*3 and 4 * 4, respectively .


The problem is , how many ways there are to tile his floor which has a area of 4*N using these four kinds of tiles ? You can assume that the number of each kind of tiles is enough.

 

 

Input

The first line contain a T. followed by T lines ,each line contain a integer N.(1<=N <=100).

 

 

Output

For each case, output the ans % 19890907.

 

 

Sample Input

 

2 1 2

 

 

Sample Output

 

1 5

 

【题意】

用1*1,2*2,3*3,4*4的砖块去铺4*n的地,输出方案数。

【解题思路】

参考:https://blog.youkuaiyun.com/acm_cxq/article/details/51189527

f[i]表示铺满前i列的方案数。f[1]=1,f[2]=5。

1.因为剩余4*1只能用1*1去填,所以f[n]=f[n-1](这种情况就包括了整个地板都用1*1去填的方案,下面肯定就不能再重复计算这个方案)

2.剩余4*2的时候,我们用2*2和1*1的方块去填可以有四种方案(注意不能不用2*2,不然就包含了全1了)。所以f[n]+=4*f[n-2]

3.剩余4*3的时候,我们用3*3和2*2和1*1(跟上面一个道理不能不使用3*3,因为使用了3*3就不能用2*2了,所以这里实际上只能用3*3和1*1),有两种方案,所以f[n]+=f[n-3]*2

4.剩余4*4的时候,我们用4*4和3*3和2*2和1*1(这里必须用4*4,其实也只能用4*4)。有一种方案,所以f[n]+=f[n-4]*1

但此时的答案还不是完整的,因为当i=3时有以下两种情况是多出来的,因为交叉,所以这两种情况在i>=3时是可以不断往前平移的。

【代码】

#include<bits/stdc++.h>
using namespace std;
const int mod=19890907;
const int maxn=105;
int f[maxn];
int main()
{
    f[0]=1;
    f[1]=1;
    f[2]=5;
    f[3]=f[2]+f[1]*4+f[0]*2+2;
    for(int i=4;i<=100;i++)
    {
        f[i]=(f[i]+f[i-1])%mod;
        f[i]=(f[i]+f[i-2]*4)%mod;
        f[i]=(f[i]+f[i-3]*2)%mod;
        f[i]=(f[i]+f[i-4])%mod;
        for(int j=3;j<=i;j++)
            f[i]=(f[i]+f[i-j]*2)%mod;
    }
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        printf("%d\n",f[n]);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值