2024-11-19每日一題

Sonatto發表於2024-11-18

臺階問題

題目描述

\(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;
}

相關文章