爬楼梯
Description
小时候,我只能一阶一阶得爬楼梯,
后来,我除了能一次爬一阶,还可以一次爬两阶,
到现在,我最多一次可以爬三阶。
那么现在问题来了,我想爬上n层楼,相邻楼层之间有一段楼梯,虽然我一次可以爬1个台阶、2个台阶和3个台阶,但是我在i与i+1层之间的楼梯上时,我不能跨越到i+1与i+2层之间的楼梯。现在有个n层的楼,知道每一段楼梯的阶数,我想知道,如果我只会往上走,并且忽略其他不在楼梯上的其他移动,共有多少种方案可以到达第n层。
Input
第一行一个整数T(0<T<=50)表示有多少组样例。
对于每一组样例:
第一行一个n(1<n<=50)表示有多少层楼。
接下来一行,包括n-1个整数xi(0<xi<=20),由下到上依次表示每段楼梯的长度。
Output
对于每组数据,输出一行表示共有多少种方案。由于答案较大,所以输出答案请对10007取模。
Sample Input
22344 5 6
Sample Output
42184
(1)递归:
到第n阶有三种方法,F(n-1)+F(n-2)+F(n-3)
int F(n)
{
if(n==1)
return 1;
if(n==2)
return 2;
if(n==3)
return 4;
else
return F(n-1)+F(n-2)+F(n-3);
}
(2)动态规划法
采用分治的策略,将问题分解成若干小问题,但是这些小问题可能重复,所以一般有状态记录表,以空间换取时间。在爬楼梯这个问题中,如在计算f(8)时,会多次重复计算f(5)这个子问题,所以为了提高效率,需要记载这些子问题的状态,避免重复计算,写出以下程序:
int state[100];
int F(n)
{
int num;
if(state[n]>0)
return state[n];//若表中已有记录直接返回即可,不必重复计算
if(n==1)
num=1;
if(n==2)
num=2;
if(n==3)
num=4;
else
num=F(n-1)+F(n-2)+F(n-3);
state[n]=num;
return num;
}
(3)循环
int x1=1,x2=2,x3=4,cnt;
for(int i=4;i<=n;i++)//此方法从4开始循环
{
cnt=x1+x2+x3;
x1=x2;
x2=x3;
x3=cnt;
}