爬楼梯问题以及拓展

爬楼梯问题以及拓展

描述
树老师爬楼梯,他可以每次走1级或者2级,输入楼梯的级数,求不同的走法数
例如:楼梯一共有3级,他可以每次都走一级,或者第一次走一级,第二次走两级
也可以第一次走两级,第二次走一级,一共3种方法。

输入
输入包含一行,一行包含一个正整数N,代表楼梯级数,1 <= N <= 5000

输出
不同的走法数,输出该层楼梯的方案数

一般思想:
相当于从终点n梯回到0梯,每次可回一步或两步,f(n)= f(n-1)+ f(n-2)。当回到1梯或2梯时,因为从0梯走到1梯时,只有走一步的方案;从0梯走到2梯时,有两次走一步的方案(方案一),有一次走两步的方案(方案二)。所以当x=1时(即回到1梯时),返回1;当x=2时(即回到2梯时),返回2。

#include<bits/stdc++.h>
using namespace std;
int fun(int x)
{
	if(x==1)
	{
		return 1;
	}
	if(x==2)
	{
		return 2;
	}
	return fun(x-1)+fun(x-2);
}

int main()
{
	int n;
	scanf("%d",&n);
	printf("%d",fun(n));
	return 0;
}

这个方法大多数人都能想到,但当N很大的时候,因为递归的调用会随着数的增长时间和空间占用增长巨快,所以一般在数很大的时候这个方法往往爆时或爆空间。

优化:

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100000;
int prog[MAXN+5];
int main()
{
	int n;
	scanf("%d",&n);
	prog[1] = 1;
	prog[2] = 2;
	for(int i = 3;i <= n;i++)
	{
		prog[i] = prog[i-1] + prog[i-2];
	}
	printf("%d",prog[n]);
	return 0;
}

这种方法直接把时间复杂度缩成了O(n),大大减少了递归的时间消耗和空间消耗。

爬楼梯类型问题的拓展

描述

现在小瓜想走上一个一共有n级的台阶,由于小瓜的腿比较短,他一次只能向上走1级或者2级台阶。小瓜想知道他有多少种方法走上这n级台阶,你能帮帮他吗?

输入
一行一个整数n(n<=100000),表示一共有n级台阶。

输出
一行一个整数,表示小瓜上台阶的方案数 对100003取余 的结果。

输入样例(1)

3

输出样例(1)

3

输入样例(2)

81470

输出样例(2)

4367

输入样例(3)

35987

输出样例(3)

36367

显然如果用递归的方法的话,那么此题就应该是凉凉了。
所以要用优化题解

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100000;
int prog[MAXN+5];
int main()
{
	int n;
	scanf("%d",&n);
	prog[1] = 1;
	prog[2] = 2;
	for(int i = 3;i <= n;i++)
	{
		prog[i] = (prog[i-1] + prog[i-2])%100003; //这里是为了数不爆炸,因为结果都是把结果对100003取余,按照提取公因数,提前把数对100003取余是没有影响的。
		
	}
	printf("%d",prog[n]);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值