动态规划——三步问题

1.问题描述

有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或者3阶。实现一种方法,计算小孩有多少种上楼梯的方式。当n比较大时(比如n=1000000),结果会很大,要求对结果进行模1000000007操作。

2.问题解决

n=1时,结果为1
n=2时,结果为2 ( 2、1 1 )
n=3时,结果为4( 3、2 1、1 2、1 1 1 )

当n比较大时,他最后一次可能上了1阶,也可能上了2阶,也可能上了3阶。
因此很容易想到递归处理的方法: f(n)=f(n-1)+f(n-2)+f(n-3).
如果直接这样计算,会出现很多不必要的重复。例如
f(6)=f(5)+f(4)+f(3),而f(5)=f(4)+f(3)+f(2),f(4)=f(3)+f(2)+f(1)在这个递归处理的过程中f(4)就被计算了两次。
因此改进方法是用一个数组记录每次计算得到的f(i),下次需要用到时就不需要再次计算了。这是很典型的动态规划的思想。

3.程序实现

int waysToStep(int n)
{
    vector<int> count(n+3);//这里采用vector的容量设置为n+3而不是n+1的原因是,当n=1时,也至少需要4个存储空间
    //如果不理解可以看下面四行代码,不管n为多大,初始状态都需要4个空间

    count[0]=0;//这个0没有实际意义,只是为了方便后面操作
    count[1]=1;
    count[2]=2;
    count[3]=4;//3阶台级有4种走法

    if(n<=3)
        return count[n];
    else
    {
        for(int i=4;i<=n;i++)
            count[i]=((count[i-1]%1000000007+count[i-2]%1000000007)%1000000007+count[i-3]%1000000007)%1000000007;
        return count[n]%1000000007;
    }
}

你可能感兴趣的:(动态规划——三步问题)