1. 程式人生 > 實用技巧 >洛谷題解P1192 臺階問題

洛谷題解P1192 臺階問題

原題傳送門

Description

\(n\) 級的臺階,從底部開始,每次可以向上邁最多 \(k\) 級臺階(最少 \(1\) 級),問到達第 \(n\) 級臺階的方案數。

Solution

這道題目可以視為 \({\tt DP}\) 模板題。

  • 狀態的表示 : 令 \(dp[i]\) 表示到第 \(i\) 級臺階的方案數。

  • 初始化 : \(dp[0]=dp[1]=1\)

    • 對於 \(dp[0]\) ,主要作用為處理一步到位的情況 (\(0\to n\)),這一步合法,故 \(dp[0]=1\)
    • 對於 \(dp[1]\) ,很顯然,走到第 \(1\) 級臺階只有一種方案
  • 狀態的轉移 : \(dp[i]=(dp[i]+dp[i-j])\%mod\ \ (i\in [2,n] , j\in [1,k])\)

    • 這裡 \(i\) 代表第 \(i\) 級臺階,用 \(j\) 來列舉 \(dp[i]\) 有可能從哪一級臺階上轉移而來。

此處狀態的轉移當且僅當 \(i\ge j\) ,目的是為了保證 \(i-j\ge 0\) (即防止從地底下開始向上爬)

\({\tt DP}\) 思路也很好想,當前臺階的方案數總和即為能轉移到當前臺階的所有臺階的方案數總和。

Code

#include<iostream>
#include<cstdio>
using namespace std;
const int Mod=1e5+3;
inline void read(int &x){
	int f=1;
	char ch=getchar();
	x=0;
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<3)+(x<<1)+(ch&15);
		ch=getchar();
	}
	x*=f;
}
inline void write(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
int n,k;
int dp[Mod];
int main(){
	read(n);read(k);
	dp[0]=1,dp[1]=1;
	for(int i=2;i<=n;i++){
		for(int j=1;j<=k;j++){
			if(i>=j){
				dp[i]=(dp[i]+dp[i-j])%Mod;
			}
		}
	}
	write(dp[n]%Mod);
	return 0;
}