洛谷题解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;
}
posted @ 2020-11-17 18:02  _pwl  阅读(288)  评论(0编辑  收藏  举报
1 2 3
4