爬楼梯问题

题目:

          假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

          注意:给定 n 是一个正整数。

解析:

假如要爬上第i阶(i>=2),则有两种方式:

    1、从第i-1阶跳一步到第i阶

    2、从第i-2阶跳两步到第i阶

记f(i)为爬上第i阶的方法数量,则f\left ( i \right )=f\left ( i-1 \right )+f\left ( i-2 \right )     i\geq 3

第一种方法(递归):

从公式上看,这是一个递归方程,所以首先想到的应该是采用递归的方法解决,其代码也非常简洁:

为了考虑数据的溢出,所以这里采用了long long int,到时候改回int就行了。

要正确的设定递归基 。众所周知,递归算法的一个缺陷是存在大量重复的计算,其时间复杂度为O\left ( 2^{n} \right )。我的机器上到n取40左右就明显速度很慢了。

#include <iostream>
#include <vector>
long long int clumbStairs(int n);
int main()
{
	int n;
	std::cout << "请输入阶梯数:";
	while (std::cin >> n && n >= 0) {
		std::cout << "共有:" << clumbStairs(n) << "种走法" << std::endl;
		std::cout << "请输入阶梯数:";
	}
	system("pause");
	return 0;
}

//这种方法时间复杂度太高
long long int clumbStairs(int n)
{
	if (n == 1)
		return 1;
	if (n == 2)
		return 2;

	return clumbStairs(n - 1) + clumbStairs(n - 2);
} 

 

第二种方法(动态规划):

   由递推方程f\left ( i \right )=f\left ( i-1 \right )+f\left ( i-2 \right )可以看出,f\left ( i \right )的结果依赖于子问题f\left ( i-1 \right )f\left ( i-2 \right )的结果,所以不难写出如下的代码。

#include <iostream>
#include <vector>
long long int clumbStairs(int n);
int main()
{
	int n;
	std::cout << "请输入阶梯数:";
	while (std::cin >> n && n >= 0) {
		std::cout << "共有:" << clumbStairs(n) << "种走法" << std::endl;
		std::cout << "请输入阶梯数:";
	}
	system("pause");
	return 0;
}

long long int clumbStairs(int n) {
   long long int Count = 0;
	if (n > 0) {
		if (1 == n)
			Count = 1;
		else if (2 == n)
			Count = 2;
		else {
			long long int* dp = new long long int[n + 1];
			dp[0] = 0, dp[1] = 1, dp[2] = 2;
			for (int i = 3; i <= n; ++i)
				dp[i] = dp[i - 1] + dp[i - 2];

			Count = dp[n];
			delete [] dp;
		}
	}
	return Count;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值