您的位置:首页 > 其它

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

2016-05-07 17:20 585 查看
#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;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息