小兔子跳n节台阶(一次最多跳m节)

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值