[Algorithm] Dynamic Programming - Fibonacci

Dynamic Programming

DP definition:

Dynamic programming is an extension of the idea of ​​divide and conquer. In layman's terms, it is the art of turning big things into small things and turning small things into nothing.

In the process of dividing and conquering large problems into small problems, the results that have been processed for these small problems are saved, and these results can be directly used when dealing with larger-scale problems later.

Dynamic programming has the following three characteristics:

        1. Break the original problem into several similar sub-problems.
        2. All subproblems only need to be solved once.
        3. Store the solutions to the subproblems.


The essence of dynamic programming is the definition of the problem state and the definition of the state transition equation (state and the recurrence relationship between states)

Dynamic programming problems are generally considered from the following four perspectives:

        1. State definition
        2. Definition of transition equation between
        states 3. State initialization
        4. Return result

Requirements for state definition: The defined state must form a recursive relationship.

Summarized in one sentence: three characteristics, four elements, two essences
Applicable scenarios: maximum/minimum value, is it feasible, is it possible, and the number of solutions


 Question 1 Fibonacci

 Fibonacci Sequence_Nioke Question Ba_Nioke Network(nowcoder.com) icon-default.png?t=M0H8https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=13&tqId=11160&tPage=1&rp=1&ru=/ta/coding-interviews&qru= /ta/coding-interviews/question-ranking

Answer - C/C++:

/*
 斐波那契数列定义:F(n)=F(n-1)+F(n-2)(n>=2,n∈N*),其中F(1)=1,F(2)=1
 方法一:递归
*/

class Solution {
public:
	int Fibonacci(int n) {
		// 初始值
		if (n <= 0) {
			return 0;
		}
		if (n == 1 || n == 2) {
			return 1;
		}
		// F(n)=F(n-1)+F(n-2)
		return Fibonacci(n - 2) + Fibonacci(n - 1);
	}
};
/*
递归的方法时间复杂度为O(2^n),随着n的增大呈现指数增长,效率低下
当输入比较大时,可能导致栈溢出
在递归过程中有大量的重复计算
*/

 


/*
方法二:动态规划
状态:F(n)
状态递推:F(n)=F(n-1)+F(n-2)
初始值:F(1)=F(2)=1
返回结果:F(N)
*/
class Solution2 {
public:
	int Fibonacci(int n) {
		// 初始值
		if (n <= 0) {
			return 0;
		}
		if (n == 1 || n == 2) {
			return 1;
		}
		// 申请一个数组,保存子问题的解,题目要求从第0项开始
		int* record = new int[n + 1];
		record[0] = 0;
		record[1] = 1;
		for (int i = 2; i <= n; i++) {
			// F(n)=F(n-1)+F(n-2)
			record[i] = record[i - 1] + record[i - 2];
		}
		return record[n];
		delete[] record;
	}
};
/*
上述解法的空间复杂度为O(n)
其实F(n)只与它相邻的前两项有关,所以没有必要保存所有子问题的解
只需要保存两个子问题的解就可以
下面方法的空间复杂度将为O(1)
*/
class Solution3 {
public:
	int Fibonacci(int n) {
		// 初始值
		if (n <= 0) {
			return 0;
		}
		if (n == 1 || n == 2) {
			return 1;
		}
		int fn1 = 1;
		int fn2 = 1;
		int result = 0;
		for (int i = 3; i <= n; i++) {
			// F(n)=F(n-1)+F(n-2)
			result = fn2 + fn1;
			// 更新值
			fn1 = fn2;
			fn2 = result;
		}
		return result;
	}
};

 

Guess you like

Origin blog.csdn.net/m0_51866180/article/details/122802365