洛谷P1192 台阶问题 //maxon.blog.luogu.org

N级的台阶,你一开始在底部,每次可以向上迈最多K级台阶(最少1级),问到达第N级台阶有多少种不同方式。

        对于此类动态规划问题,可以联想斐波那契数列,如果迈上终点台阶时,可以在原先的第N-1级至第N-K级(共K级)基础上再多迈一次,也就是说F(N)=F(N-1)+F(N-2)+...+F(N-K)。那为什么不在加1呢?因为将所有方案加到一起就是一次可能性的整合,即到了F(N-1)~F(N-K) 这个区间内就是等同于到F(N)了。但是它们都可以通过这种递推方式计算。比如在10阶时可以迈三步,那么迈一步或者三步就是一次选择,到达第8阶或第9阶之前是怎么选择就不用考虑。

      F(N-1)~F(N-K)可以用一层循环来表示,截止当前的阶梯数i,每次可走的阶梯数j(1~K之间),并且不能超过;则有如下代码:

 1 #include<iostream>
 2 using namespace std;
 3 //N阶梯K步时的和为(N-K)到N阶梯K步的和。
 4 const int MAX = 100010;         //台阶不超过10000级
 5 int steps[MAX];
 6 
 7 int main()
 8 {
 9     int total,step,i,j;            
10     cin>>total>>step;                          //输入台阶数和可跨的步数
11     for(i=1;i<=step;i++) steps[i] = 1;       //给初值
12 
13     for(i=2;i<=total;i++)
14     {
15         for(j=1;j<=step&&j<=i;j++)
16         {
17             steps[i] = (steps[i]+steps[i-j])%(1e+9);    //取模以免溢出
18         }
19 
20 /*
21         也可采用此方式
22       for(j=i-1;j>i-step&&j>0;j--)
23         {
24             steps[i] = (steps[i]+steps[j])%(1e+9);    //取模以免溢出
25         }
26     
27 */
28     }
29     cout<<steps[total]<<endl;
30     return 0;
31 }

 

同时转载大佬总结http://cppblog.com/menjitianya/archive/2015/10/23/212084.html

posted on 2019-03-22 16:13  tobyte  阅读(170)  评论(0编辑  收藏  举报