Q10斐波那契数列及变体的动态规划解法

斐波那契数列


数列:
f ( n ) = { 0 n = 0 1 n = 1 f ( n 1 ) + f ( n 2 ) n 2 f(n)=\left\{ \begin{array}{lcl} 0 & & {n=0}\\ 1 & & {n=1}\\ f(n-1)+f(n-2) & & {n\geq2} \end{array} \right.

递归实现形式

虽然用递归形式很简洁,但是因为重复计算,导致计算效率非常低,100几乎计算不出来。

//计算100时,根本算不出来
long long fibonacci1(unsigned int n)
{
	if (n == 0)	return 0;
	if (n == 1)	return 1;
	return fibonacci1(n - 2) + fibonacci1(n - 1);
}

从下面的图可以看出来,f6,f5,f4都已经重复计算。

f8
f7
f6
f6
f5
f5
f4

自下而上的计算方法

保留已经计算过程的 f(n-1)f(n-2)。大大提高计算效率

long long fibonacci2(unsigned int n)
{
	if (n <= 0) return 0;
	if (n == 1) return 1;
	long long fMinus1 = 1;
	long long fMinus2 = 0;
	long long f = 0;
	for (int i=2; i<=n; ++i)
	{
		f = fMinus1 + fMinus2;
		fMinus2 = fMinus1;
		fMinus1 = f;
	}
	return f;
}

斐波那契额数列的变体

青蛙跳台阶

一次可以跳一阶,也可以跳两阶。求跳上n个台阶的所有可能跳法f(n)。

跳n阶时,第一次跳有两种选择

  1. 跳1阶,剩下的跳法就是f(n-1)。
  2. 跳2阶,剩下的跳法就是f(n-2)。

故 f(n)=f(n-1)+f(n-2)。

青蛙跳阶的另一变体:

青蛙每次可以跳任意个,那么

  1. f(1) = 1
  2. f(2) = 2
  3. f(3) = f(2)+f(1)+1=4
  4. f(4) = f(3)+f(2)+f(1)+1 = 8 = f(3)+ f(3)
  5. f(n) = 2*f(n-1)= 2 n 1 2^{n-1}

1x2小矩形覆盖 2xn大矩形

1x2小矩形覆盖方法也有两种,横着和竖着

那第一次覆盖时,也有两种,

  1. 竖着覆盖,那么还剩的格子为 2x(n-1),剩下的覆盖方法为 f(n-1)
  2. 横着覆盖,那么还需要一个把小矩形下面的覆盖掉,这是确定的。那么剩下的格子数为2x(n-2),可能的覆盖方法为f(n-2)。

故 f(n)=f(n-1)+f(n-2)

发布了48 篇原创文章 · 获赞 10 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/mhywoniu/article/details/104906881