臺階問題
題目描述
有 \(N\) 級臺階,你一開始在底部,每次可以向上邁 \(1\sim K\) 級臺階,問到達第 \(N\) 級臺階有多少種不同方式。
輸入格式
兩個正整數 \(N,K\)。
輸出格式
一個正整數 \(ans\pmod{100003}\),為到達第 \(N\) 級臺階的不同方式數。
樣例
輸入
5 2
輸出
8
資料範圍
對於 \(100\%\) 的資料,\(1\leq N\leq100000\),\(1\leq K\leq100\)。
思路
和走樓梯很類似,可以把走樓梯問題看作這題K=2的特殊情況
我們可以用和走樓梯一樣的分析方法:
每次可以前進1~K級臺階,那麼在第 i 級臺階,可以是從第 i - 1 級到第 i - k 級的任意臺階邁過來,這樣邁到第 i 級臺階的方案數就是邁到第 i - 1, i - 2, i - 3... i -k 級臺階的方案數之和,所以\(f[i]= f[i-1]+f[i-2]+...+f[i-k]\)
分析時間複雜度:
由於幾乎每一個 i 都要列舉 K 個數,所以時間複雜度為\(O(K*N)\),最大為\(10^7\),不會超時
邊界情況:
顯然第1級方案數為1,而對高度小於K的臺階顯然不可能從第 -1 -2 -3等幽默的臺階邁過來,所以記得2~ K-1 級臺階是\(\sum_{0}^{i-1}f[j]\)而不是\(\sum_{i-k}^{i-1}f[j]\)
程式碼
#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[200100];
int main()
{
scanf("%d%d",&n,&k);
a[0]=1;
a[1]=1;
for(int i=2;i<=n;i++) {
for(int j=1;j<=min(k,i);j++) {
a[i]=(a[i]+a[i-j])%100003;
}
}
printf("%d\n",a[n]);
return 0;
}