斐波那契数列、跳台阶、变态跳台阶、矩形覆盖

#include<iostream>
#include<math.h>
using namespace std;

//斐波那契数列
class Solution
{
public:
	int Fibonacci1(int n)
	{
		/*
		*第一种解法:递归————从上往下计算,重复计算太多,效率太低,不能满足时间要求
		*/
		if (n == 0)
			return 0;
		if (n == 1)
			return 1;

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

	int Fibonacci2(int n)
	{
		/*
		*第二种解法:从下往上计算,减少重复计算
		*/
		int n0 = 0, n1 = 1;
		int ret;
		if (n == 0)
			ret = 0;
		if (n == 1)
			ret = 1;

		for (int i = 2; i <= n; i++)
		{
			ret = n0 + n1;

			n0 = n1;
			n1 = ret;
		}
		return ret;
	}
};

//扩展1:青蛙跳台阶————一次可以跳1级,也可以跳2级,求跳N级的跳法种数。
class Solution2
{
public:
	int jumpFloor1(int n)
	{
		/*
		*n=1:只有1种跳法;
		*n=2:两种跳法;
		*n>2:假设跳N级的跳法有f(n)种,
		*         (1)第一次跳,跳1级,则剩下N-1级的跳法有f(n-1)种;
		*         (2)第一次跳,跳2级,则剩下N-2级的跳法有f(n-2)种;
		*     所以:f(n) = f(n-1) + f(n-2)。
		*/
		//if (n == 0 || n == 1)
		if (n == 1)
			return 1;
		if (n == 2)
			return 2;

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

	int jumpFloor2(int number) {

		int n0 = 1, n1 = 2;
		int ret;
		if (number == 1)
			ret = 1;
		if (number == 2)
			ret = 2;

		for (int i = 3; i <= number; i++)
		{
			ret = n0 + n1;

			n0 = n1;
			n1 = ret;
		}
		return ret;
	}

	int jumpFloor3(int number) {
		/*
		*第3种解法:滚动数组
		*/
		int F[3] = { 0, 1, 2 };
		if (number <= 2)
		{
			return F[number];
		}
		for (int i = 3; i <= number; i++)
		{
			F[0] = F[1];
			F[1] = F[2];
			F[2] = F[0] + F[1];
		}
		return F[2];

	}
};

//扩展2:青蛙变态跳台阶————一次可以跳1级,也可以跳2级.....,也可以跳上N级台阶,求跳N级的跳法种数。
class Solution3
{
public:
	int jumpFloorII(int number) {
		/*
		*第1种解法:递归————从顶往下计算
		*     f(n) = f(0)+f(1)+f(2)+f(3)+......+f(n-2)+f(n-1) ———— 第一次跳n,第一次跳n-1......
		*又   f(n-1) = f(0)+f(1)+f(2)+f(3)+......+f(n-2)
		*所以 f(n) - f(n-1) = f(n-1) -----> f(n) = 2 * f(n-1)
		*/

		if (number == 1)
			return 1;

		return 2 * jumpFloorII(number - 1);
	}

	int jumpFloorII1(int number) {
		/*
		*第2种解法:从下往顶计算
		*最后剩下0个台阶,暂且定为0,直接跳n个台阶上来,显然只有一种方法(也就是说,对于任何一个“N”,我们都可以直接跳“N”,所以我们每次循环首先自加1就行了)
		*最后剩下1个台阶,那么共有(第n-1个台阶的方法数)种;
		*最后剩下2个台阶,共有(第n-2个台阶的方法数)种;
		*....
		*最后剩下n-1个台阶,只有一种方法。
		*累加上面每一种的方法,就是跳到第n阶台阶的总的跳法种数
		*/
		long long int arr[100] = { 0, 1 };      //限定最多跳100级
		for (int i = 2; i < 100; i++)
		{
			int j = i - 1;
			arr[i]++;      //直接跳跃到本身的"N"
			while (j)
			{
				arr[i] = arr[i] + arr[j];
				j--;
			}
		}
		return arr[number];
	}

	int jumpFloorII2(int number) {
		/*
		*第3种解法:用数学归纳法证明f(n)=2^(n-1)。
		*/
		return pow(2, number - 1);
	}

	int jumpFloorII3(int number) {
		/*
		*第4种解法:滚动数组
		*/
		int F[2] = { 0, 1 };
		if (number < 2)
			return F[number];

		for (int i = 2; i <= number; i++)
		{
			F[0] = F[1];
			F[1] = 2 * F[0];
		}
		return F[1];
	}
};

//扩展3:矩形覆盖————用number个2*1的矩形去覆盖更大的矩形(number*2),求总共的方法数。
class Solution4 {
public:
	int rectCover(int number) {
		if (number <= 0 || number == 1)
			return 1;
		if (number == 2)
			return 2;

		return rectCover(number - 1) + rectCover(number - 2);
	}

	int rectCover1(int number) {
		if (number == 1)
			return 1;
		if (number == 2)
			return 2;

		int n1 = 1, n2 = 2, tmp = 0;
		for (int i = 3; i <= number; i++)
		{
			tmp = n1 + n2;

			n1 = n2;
			n2 = tmp;
		}
		return tmp;
	}
};

void main()
{
	Solution4 s;
	cout << s.rectCover1(5) << endl;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值