数楼梯(加强版)

数楼梯(加强版)

题目背景:

  小明一天放学回家,看到从1楼到2楼共有n个台阶,因为好奇,他想尝试一下总共有几种方案到二楼?他可以1步,2步,3步的跳,不能跳3步以上.
  他试了很多次都没有解决这个问题,于是请求聪明的你帮忙解决这个问题.

题目描述:

1楼到2楼楼梯有n级台阶。小明每次可以爬一格、走两格或者跨三格。问最终有几种方案到二楼?答案对998244353取模。

输入格式:

一行一个数n。

输出格式:

一行一个数,表示方案数。

输入输出样例

输入 #1:

3

输出 #1:

4

输入 #2:

5

输出 #2:

13

提示说明:

 n≤1000  
 时间:1000ms   
 空间:256M  
 (上楼梯时不能往回走)
 如果觉得这道题太难可以前往P1255先做数楼梯简单版:
 https://www.luogu.com.cn/problem/P1255

思路:

  1.暴力法

  很容易看出来,这是一道递归题,我们可以用暴力递归来解决。

#include<iostream> 
using namespace std; 
static const int mod=998244353;
long long sum=0;
int n;
long long fun(int x){
	if(x==n)
	  return 1;
	if(x>n)
	  return 0;
	long long s1=0,s2=0,s3=0;
	s1+=fun(x+1)%mod;
	s2+=fun(x+2)%mod;
	s3+=fun(x+3)%mod;
	return (s1+s2+s3)%mod;
}
int main(){
	cin>>n;
	cout<<fun(0)<<endl;		
    return 0;
}

但是这个份代码会超时,非常慢,所以要进行优化!

2.递推法

我们用 f(x) 表示爬到第 x 级台阶的方案数,考虑最后一步可能跨了一级台阶,也可能跨了两级台阶,所以我们可以列出如下式子:
f(x)=f(x−1)+f(x−2)
它意味着爬到第 x 级台阶的方案数是爬到第 x−1 级台阶的方案数和爬到第 x−2 级台阶的方案数的和。很好理解,因为每次只能爬 1 级或 2 级,所以 f(x) 只能从 f(x−1)和 f(x−2) 转移过来,而这里要统计方案总数,我们就需要对这两项的贡献求和。

  以上是动态规划的转移方程,下面我们来讨论边界条件。我们是从第 0 级开始爬的,所以从第 0 级爬到第 0 级我们可以看作只有一种方案,即 f(0)=1;从第 0 级到第 1 级也只有一种方案,即爬一级,f(1)=1。这两个作为边界条件就可以继续向后推导出第 n 级的正确结果。我们不妨写几项来验证一下,根据转移方程得到 f(2)=2,f(3)=3,f(4)=5,……,我们把这些情况都枚举出来,发现计算的结果是正确的。

  我们不难通过转移方程和边界条件给出一个时间复杂度和空间复杂度都是 O(n)的实现,但是由于这里的 f(x) 只和 f(x−1)) 与 f(x−2)有关,所以我们可以用「滚动数组思想」把空间复杂度优化成 O(1)。下面的代码中给出的就是这种实现。

#include<iostream> 
using namespace std; 
static const int mod=998244353;
void fun(int n){
	long long max[1001];
	int i=0;
	max[0]=1;
	max[1]=2;
	max[2]=4;
	for(int j=3;j<n;j++)
	  max[j]=(max[j-1]+max[j-2]+max[j-3])%mod;
	cout<<max[n-1]<<endl;
}
int main(){
	int n;
	cin>>n;
	fun(n);		
    return 0;
}

总结:

  对于这道题,有些像斐波那契数列,需要将递归进行优化才可以解决。

题目链接:

数楼梯(加强版) - 洛谷https://www.luogu.com.cn/problem/U267577

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙星尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值