题目描述:
有N级台阶,你一开始在底部,每次可以向上迈 $1\sim K$ 级台阶,问到达第 $N$ 级台阶有多少种不同方式。
输入格式:
两个正整数N,K。
输出格式:
一个正整数ans(mod100003),为到达第N级台阶的不同方式数。
样例 #1
样例输入 #1
5 2
样例输出 #1
8
提示:
- 对于20%的数据,1≤N≤10,1≤K≤3;
- 对于40%的数据,1≤N≤1000;
- 对于100%的数据,1≤n≤100000,1≤K≤100。
分析:
这题有两个做法,先说第一种吧。
方法一:
k=1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 |
k=2 | 1 | 2 | 4 | 7 | 13 | 24 | 44 | 81 |
k=3 | 1 | 2 | 4 | 8 | 15 | 29 | 56 | 108 |
k=3 | 1 | 2 | 4 | 8 | 16 | 31 | 61 | 120 |
这是作者举得几个例子,有人肯能发现了前k项是一个等比数列,比值是2。
当n<=k时,第n项=(2*前一项)%100003
那n>k时呢?
当n>k时,第n项=(上一项*2-第i-1-k项)%100003
那第一种的代码就有了:
#include <bits/stdc++.h>
using namespace std;
const int mod=100003;
int a[100010];
int main()
{
int n,k;
cin>>n>>k;
a[0]=a[1]=1;//初始化
for(int i=2;i<=n;i++)
{
if(i<=k)
{
a[i]=(a[i-1]*2)%mod;//取模!!
}
else
{
a[i]=((a[i-1]*2)-a[i-k-1])%mod;
}//按规律写就好了
}
cout<<(a[n]+100003)%mod;//这里再取模是为了防止负数
return 0;
}
Tips:
取模!!
方法二:
这个方法其实是dp动态规划,但他于普通的动态规划不同,在这里dp[i]代表第i阶的走法,那差不多就能写了,别忘了取模!!
#include <bits/stdc++.h>
using namespace std;
int dp[100010];
const int mod=100003;
int main()
{
int n,k;
cin>>n>>k;
dp[0]=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;
}
}
}//动态规划模板
cout<<dp[n]%mod;//防止负数
return 0;
}
其实我个人推荐第一种,因为那是真的简单,不管你会哪种方法,都希望对你有帮助!
验证方式:洛谷P1192 台阶问题直接交就能AC
有问题的话可以在评论区讨论!!