update string
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
# 动态规划DP
|
||||
|
||||
动态规划(英语:Dynamic programming,简称 DP),通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
|
||||
|
||||
## 动态规划DP
|
||||
|
||||
复杂问题不能分解成几个子问题,而分解成一系列子问题;
|
||||
|
||||
DP通常基于一个递推公式及一个(或多个)初始状态,当前子问题解由上一次子问题解推出。
|
||||
复杂问题不能分解成几个子问题,而分解成一系列子问题;DP通常基于一个递推公式及一个(或多个)初始状态,当前子问题解由上一次子问题解推出。
|
||||
|
||||
状态
|
||||
状态转移方程
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
|
||||
|
||||
## 回溯法
|
||||
# 回溯法
|
||||
|
||||
也叫 `试探法`。 是一种选优搜索法,按照选优条件搜索,当搜索到某一步,发现原先选择并不优或达不到目标,就退回重新选择。
|
||||
|
||||
回溯算法其实就是我们常说的 DFS 算法,本质上就是一种暴力穷举算法。
|
||||
|
||||
一般步骤
|
||||
|
||||
@@ -14,11 +13,20 @@
|
||||
回溯法求解问题时,一般是一边建树,一边遍历该树;且采用非递归方法。
|
||||
|
||||
|
||||
#### 八皇后问题
|
||||
## 全排列问题
|
||||
|
||||
> n 个不重复的数,全排列共有 n! 个
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 八皇后问题
|
||||
|
||||
8x8的国际象棋棋盘上放置8个皇后,使得任何一个皇后都无法直接吃掉其他的皇后。任意2个皇后都不能处于同一个 横线,纵线,斜线上。
|
||||
|
||||
分析
|
||||
|
||||
1. 任意2个皇后不能同一行,也就是每个皇后占据一行,通用的,每个皇后也要占据一列
|
||||
2. 一个斜线上也只有一个皇后
|
||||
|
||||
@@ -26,6 +34,7 @@
|
||||
|
||||
#### 其它案例
|
||||
|
||||
迷宫问题
|
||||
* 迷宫问题
|
||||
* 全排列
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
|
||||
|
||||
## 递归
|
||||
# 递归
|
||||
|
||||
递归是一种设计和描述算法的有力工具。 递归算法执行过程分 `递推` 和 `回归` 两个阶段
|
||||
|
||||
@@ -11,20 +9,65 @@
|
||||
2) 确定边界条件
|
||||
|
||||
|
||||
#### 斐波那契数列
|
||||
## 斐波那契数列
|
||||
|
||||
fib(n)=fib(n-1)+fib(n-2)
|
||||
|
||||
|
||||
递归实现
|
||||
```
|
||||
#### 递归实现
|
||||
|
||||
```
|
||||
|
||||
非递归实现
|
||||
int fib(int N) {
|
||||
if (N == 1 || N == 2) return 1;
|
||||
return fib(N - 1) + fib(N - 2);
|
||||
}
|
||||
```
|
||||
|
||||
这个递归的算法效率非常差,存在大量重复计算。
|
||||
|
||||
|
||||
#### 非递归实现
|
||||
|
||||
我们可以有一个【缓存】,每次遇到一个子问题先去「缓存」里查一查,如果发现之前已经解决过这个问题了,直接把答案拿出来用,不要再耗时去计算了。
|
||||
|
||||
```
|
||||
public int fib(int n){
|
||||
if (n == 0) return 0;
|
||||
|
||||
//缓存
|
||||
int[] dp = new int[n + 1];
|
||||
|
||||
// base case
|
||||
dp[0] = 0; dp[1] = 1;
|
||||
|
||||
// 状态转移
|
||||
for (int i = 2; i <= n; i++) {
|
||||
dp[i] = dp[i - 1] + dp[i - 2];
|
||||
}
|
||||
|
||||
return dp[n];
|
||||
}
|
||||
```
|
||||
|
||||
说一个细节优化点,当前状态只和之前的两个状态有关,其实并不需要那么长的一个 DP table 来存储所有的状态,只要想办法存储之前的两个状态就行了。所以,可以进一步优化,把空间复杂度降为 O(1):
|
||||
|
||||
```
|
||||
int fib(int n) {
|
||||
if (n < 1) return 0;
|
||||
if (n == 2 || n == 1)
|
||||
return 1;
|
||||
int prev = 1, curr = 1;
|
||||
for (int i = 3; i <= n; i++) {
|
||||
int sum = prev + curr;
|
||||
prev = curr;
|
||||
curr = sum;
|
||||
}
|
||||
return curr;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### 其它案例
|
||||
|
||||
|
||||
Reference in New Issue
Block a user