洛谷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