题1 台阶问题(stair)
【问题描述】
有N级的台阶,你一开始在底部,每次可以向上迈最多K级台阶(最少1级),问到达第N级台阶有多少种不同方式。
【输入文件】
输入文件stair.in的仅包含两个正整数N,K。
【输出文件】
输入文件stair.out仅包括1个正整数,为不同方式数,由于答案可能很大,你需要输出mod 100003后的结果。
【样例输入】
5 2
【样例输出】
8
【数据规模与约定】
对于20%的数据,有N ≤ 10, K ≤ 3;
对于40%的数据,有N ≤ 1000;
对于100%的数据,有N ≤ 100000,K ≤ 100。
猜想:最早的台阶问题最多只能迈两阶,当前阶的方式数是前两阶的和,那这题最多迈K阶会不会是前K阶的和是当前阶的方式数呢?
通过列表发现规律 :
(1)当每次可以向上迈最多K级台阶(最少1级)时,的不同种方式数为前K项相加。
(2)当不足够有K项时, 说明当前的台阶不够K阶,那么当前的台阶方式数只需将第1项加到当前项的前一项的和再加1。
若当前共有100阶,最多能迈10阶
- 那么到达第3阶的方式数a[3]=a[1]+a[2]+1,其中+1是一脚迈3阶。
- 同理得 a[4]=a[1]+a[2]+a[3]+1,a[5] = a[1]+a[2]+a[3]+a[4]+1
- 到达大于10阶的方式数才是前10项的和 。
#include<iostream>
using namespace std;
const int mod = 100003,N = 100010, K = 110;
int a[N];
int sum,ans;
int main(){
freopen("stair.in","r",stdin);
freopen("stair.out","w",stdout);
int n,k;
cin>>n>>k;
a[1] = 1;
sum = a[1];
//计算k阶及之前各有多少方式(不足够k阶的方式)
for(int i = 2; i <= k; i++){
a[i] = (sum + 1)%mod;
sum = (sum + a[i])%mod;
}
//通过计算后的前k阶方式数推导后面的方式数
for(int i = k+1; i <= n; i++){
a[i] = sum;
sum = (sum + a[i] - a[i-k]) % mod;
//if(sum < 0) sum += mod; //余数小于0时加上除数即可
}
if(a[n] < 0) a[n] += mod; //余数小于0时加上除数即可
cout<<a[n]<<endl;
return 0;
}