Description
小青蛙跳楼梯大家应该都很熟悉吧?小青蛙每次最多跳两节,求跳n个台阶有多少种方法。
现在,小兔子也想跳,而且它比小青蛙厉害,一次最多可以跳m节台阶(1<m<1000000)。
请问,小兔子跳n节台阶一共有多少种方法呢?
Input
有两行,第一行为一个整数n(1<n<1000000),第二行为一个整数m
Output
输出方法总数%1000000007的结果
Sample Input
3
3
Sample Output
4
思路:
当n<=m时,小兔子可以跳到任意地方,对于第n阶台阶之前的n-1阶台阶,都有经过和不经过两种选择,第n阶肯定是要经过的嘛。所以从第一阶到第n阶共有2的n-1次方种选择。
当n>m 时,我们定义dp[i]为跳到第n节的方法数。
1)i<m时,同理,2n−1。
2)之后的每个台阶,都可以从之前相差小于等于m节的地方一次跳过来。则 dp[i]=dp[i−1]+dp[i−2]+….+dp[i−m]
我们不需要每次都要计算这mm项的和.利用 sum 变量记录并更新(减过期的数,加新增的数)即可。
#include<bits/stdc++.h>
const int mod = 1000000007;
const int maxn = 1e6;
using namespace std;
typedef long long ll;
int n,m;
ll dp[maxn + 5];
ll powmod(ll a,ll b)
{
a %= mod;
ll res=1;
while(b)
{
if(b & 1) res= res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
dp[i] = powmod(2, i - 1);
if(m>=n)
cout << dp[n] << endl;
else
{
for(int i = m + 1; i <= n; ++i)
for(int j = 1;j <= m; ++j)
dp[i] = (dp[i] + dp[i - j]) % mod;
cout << dp[n] << endl;
}
return 0;
}