hdu-2606 Renovation Problem(递推)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2606

Renovation Problem

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


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
题意:输入一个N,表示有一个4*N的地板。现在有四种砖块,分别为1*1,2*2,3*3,4*4.问用这四种砖块填满地板一共有几种方案。
思路:按照常规思维我们可以想到: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
噫,怎么还是WA= =?? 因为我们还漏算了一种情况。我们用2*2的时候会产生一个交叉的情况,而这种情况不属于以上任何一种情况。
ex:.表示砖块,1表示未铺的地板
4*3的地板情况:
..11
....
11..
11..
....
..11
是不是显而易见? 这种情况涵盖了三行而不属于以上四种情况的任何一种,所以当我们对每一行做完以上四个操作的时候我们还需要考虑这两种情况。
而因为这两种情况在n>=3的情况下每行都会出现,所以我们需要枚举一遍。如果你能看懂这五个操作,相信就能完美AC了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mod 19890907
int f[105];
void init()
{
    f[0]=1;  f[1] = 1, f[2] = 5, f[3] = f[2] + f[1]*4+2*f[0]+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 k=3; k<=i; k++)
            f[i]=(f[i]+2*f[i-k])%mod;
    }
}
int main()
{
    int T,n;
    init();
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        printf("%d\n",f[n]);
    }
    return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值