爬樓梯問題總結 (遞推)


超級樓梯

鏈接:

http://acm.hdu.edu.cn/showproblem.php?pid=2041

題意:

有一樓梯共M級,剛開始時你在第一級,若每次只能跨上一級或二級,要走上第M級,共有多少種走法?

分析:

首先題目限制只能走一級或者兩級, 所以逆向思考一下, 要到達n級樓梯, 只有兩種方式,從(n-1)級 或 (n-2)級到達的。

所以可以用遞推的思想去想這題,假設有一個數組s[n], 那么s[1] = 1(由於一開始就在第一級,只有一種方法), s[2] = 1(只能從s[1]上去 沒有其他方法)。

那么就可以推出s[3] ~ s[n]了。

下面繼續模擬一下, s[3] = s[1] + s[2], 因為只能從第一級跨兩步, 或者第二級跨一步。

如果是第一級跨一步再跨一步, 就等於第二步跨一步,這就重復了。(因為每一級都是相差1, 所以不能有從哪一級跨出一步這種走法, 除了跨出一級就到達目的地)。

 

 

frog

鏈接:

http://acm.dhu.edu.cn/contest/view.html?id=873&index=2

題意:

這題可以說是上一題的加強版,可以看成有M級樓梯,剛開始你在0級(平地), 每次能跨L步,共有多少種走法。

分析:

這題可以類比上一題, 如果上一題只能走兩步的話,走上n級考慮(n-1)和(n-2),那么這題可以看成走上n級考慮(n-1),(n-2)...(n-L)級。

那么同理 s[0] = 1; s[1] = 1;

然后s[2]~s[L]就可以推了(因為這一部分的前面都不足n級,特殊考慮)

for 2~L ← i

  s[i] = sum(s[0],s[i])

然后s[L+1]到s[n]的部分可以(這一部分前面肯定有n級, 一般情況)

for L+1 ~ n ← i

  s[i] = sum(s[i-1 - L],s[i-1])  //總長為L的樓梯的方法數之和

最后輸出s[n]即可。

該題需要 % 1e9+7, 注意同余的特性:

(a+b) mod n = (a mod n + b mod n) mod n

(a-b) mod n = (a mod n - b mod n + n) mod n (因為a mod n 可能小於 b mod n  所以需要加上一個n)

#include<bits/stdc++.h>
using namespace std; int n , l; const int maxn = 100005; const long long mod = 1e9 + 7; long long dp[maxn]; int main() { while(~scanf("%d %d", &n, &l)) { if(l == 1) { printf("1\n"); continue; } dp[0] = dp[1] = 1; int t = dp[0] + dp[1]; for(int i = 2; i <= l; i ++) { dp[i] = t; t += dp[i]; t %= mod; } for(int i = l+1; i <= n; i++) { dp[i] =((2*dp[i-1])%mod - (dp[i-1-l]%mod) + mod) % mod; //這部分可以推一下, 如 L = 2時, // dp[4] = dp[3] + dp [2]; //那么 dp[5] = dp[4] + dp[3] = dp[4] + dp[4] - dp[2] = 2*dp[4] - dp[2];
 } printf("%lld\n", dp[n]); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM