Skip to content

Commit

Permalink
feat: update contents
Browse files Browse the repository at this point in the history
  • Loading branch information
HarleysZhang committed Dec 19, 2022
1 parent 25d2d2d commit 6dd7fa4
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 16 deletions.
24 changes: 12 additions & 12 deletions 3-data_structure-algorithm/dp/动态规划理论.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@

> 学习目标:彻底搞懂最优子结构、无后效性和重复子问题。什么样的问题可以用动态规划解决?解决动态规划问题的一般思考过程是什么样的?贪心、分治、回溯、动态规划这四种算法思想又有什么区别和联系?
### 一,“一个模型三个特征”理论讲解
## 一,“一个模型三个特征”理论讲解

一个模型指的是适合用动态规划算法解决的问题的模型,这个模型也被定义为“多阶段决策最优解模型”。具体解释如下:

一般是用动态规划来解决**最优**问题。而解决问题的过程,需要经历多个决策阶段。每个决策阶段都对应着一组状态。然后我们寻找一组**决策序列**,经过这组决策序列,能够产生最终期望求解的最优值。

#### 1. 最优子结构
### 1. 最优子结构

最优子结构指的是,问题的最优解包含子问题的最优解。反过来说就是,我们可以通过子问题的最优解,推导出问题的最优解。把最优子结构,对应到前面定义的动态规划问题模型上,就是**后面阶段的状态可以通过前面阶段的状态推导出来**

#### 2. 无后效性
### 2. 无后效性

无后效性有两层含义,第一层含义是,在推导后面阶段的状态的时候,我们只关心前面阶段的状态值,不关心这个状态是怎么一步一步推导出来的。第二层含义是,某阶段状态一旦确定,就不受之后阶段的决策影响。无后效性是一个非常“宽松”的要求。只要满足前面提到的动态规划问题模型,其实基本上都会满足无后效性。

#### 3. 重复子问题
### 3. 重复子问题

不同的决策序列,到达某个相同的阶段时,可能会产生重复的状态。

#### 4. “一个模型三个特征”实例剖析
### 4. “一个模型三个特征”实例剖析

结合一个具体的动态规划问题更能详细理解上述理论,**示例问题描述如下**

Expand All @@ -46,11 +46,11 @@
min_dist(i, j) = min(min_dist(i-1,j), min_dist(i, j-1))
```
### 二,两种动态规划解题思路总结
## 二,两种动态规划解题思路总结
知道了如何鉴别一个问题是否可以用动态规划来解决,接下来就是总结动态规划解决问题的一般思路。解决动态规划问题,一般有两种思路。分别叫作:状态转移表法和状态转移方程法。
#### 1. 状态转移表法
### 1. 状态转移表法
**一般能用动态规划解决的问题,都可以使用回溯算法的暴力搜索解决**。所以,当我们拿到问题的时候,我们可以先用简单的回溯算法解决,然后定义状态,每个状态表示一个节点,然后对应画出递归树。从递归树中,我们很容易可以看出来,是否存在重复子问题,以及重复子问题是如何产生的。以此来寻找规律,看是否能用动态规划解决。
Expand Down Expand Up @@ -131,7 +131,7 @@ public:

![leetcode64 动态规划解法代码提交记录](../../data/images/leetcode64_commit.png)

#### 2. 状态转移方程法
### 2. 状态转移方程法

根据最优子结构,写出递归公式,也就是所谓的状态转移方程。**状态转移方程,或者说递归公式是解决动态规划的关键**。递归加“备忘录”的方式,将状态转移方程翻译成来 `C++` 代码。

Expand Down Expand Up @@ -171,24 +171,24 @@ public:

![leetcode64 动态规划解法代码提交记录](../../data/images/leetcode64_commit2.png)

### 三,四种算法比较分析
## 三,四种算法比较分析

如果将这四种算法思想分一下类,那贪心、回溯、动态规划可以归为一类,而分治单独可以作为一类,因为它跟其他三个都不大一样。为什么这么说呢?因为前三个算法解决问题的模型,都可以抽象成**多阶段决策最优解**模型,而分治算法解决的问题尽管大部分也是最优解问题,但是,大部分都不能抽象成多阶段决策模型。

尽管动态规划比回溯算法高效,但是,并不是所有问题,都可以用动态规划来解决。能用动态规划解决的问题,需要满足三个特征,最优子结构、无后效性和重复子问题。在重复子问题这一点上,动态规划和分治算法的区分非常明显。分治算法要求分割成的子问题,不能有重复子问题,而动态规划正好相反,动态规划之所以高效,就是因为回溯算法实现中存在大量的重复子问题。

贪心算法实际上是动态规划算法的一种特殊情况。它解决问题起来更加高效,代码实现也更加简洁。不过,它可以解决的问题也更加有限。它能解决的问题需要满足三个条件,最优子结构、无后效性和贪心选择性(这里我们不怎么强调重复子问题)。其中,最优子结构、无后效性跟动态规划中的无异。“贪心选择性”的意思是,通过局部最优的选择,能产生全局的最优选择。每一个阶段,我们都选择当前看起来最优的决策,所有阶段的决策完成之后,最终由这些局部最优解构成全局最优解。

### 四,内容总结
## 四,内容总结

什么样的问题适合用动态规划解决?这些问题可以总结概括为“一个模型三个特征”。其中,“一个模型”指的是,问题可以抽象成分阶段决策最优解模型。“三个特征”指的是最优子结构、无后效性和重复子问题。

哪两种动态规划的解题思路?它们分别是状态转移表法和状态转移方程法。其中,状态转移表法解题思路大致可以概括为,**回溯算法实现 - 定义状态 - 画递归树 - 找重复子问题 - 画状态转移表 - 根据递推关系填表 - 将填表过程翻译成代码**。状态转移方程法的大致思路可以概括为,**找最优子结构 - 写状态转移方程 - 将状态转移方程翻译成代码**

#### 练习题
### 练习题

假设我们有几种不同币值的硬币 v1,v2,……,vn(单位是元)。如果我们要支付 w 元,求最少需要多少个硬币。比如,我们有 3 种不同的硬币,1 元、3 元、5 元,我们要支付 9 元,最少需要 3 个硬币(3 个 3 元的硬币)。

### 参考资料
## 参考资料

[动态规划理论:一篇文章带你彻底搞懂最优子结构、无后效性和重复子问题](https://time.geekbang.org/column/article/75702)
8 changes: 4 additions & 4 deletions 3-data_structure-algorithm/hash_table/哈希算法.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### 一,什么是哈希算法
# # 一,什么是哈希算法

哈希和散列其实意思是一样的,只是中文翻译的区别,英文是 `Hash`

Expand All @@ -20,7 +20,7 @@
3. 冲突的概率要很小。
4. 执行效率要高,理论上来说执行时间越长的冲突概率越小。

### 二,哈希算法的应用场景
# # 二,哈希算法的应用场景

**1,安全加密**

Expand Down Expand Up @@ -78,10 +78,10 @@

这就是**一致性哈希算法**。假设我们有 $k$ 个机器,数据的哈希值的范围是$[0, MAX]$,我们将整个范围划分成 $m$ 个小区间($m$ 远大于 $k$),那么每个机器就负责 $m/k$ 个小区间。当有新机器加入的时候,我们就将某几个小区间的数据,从原来的机器中搬移到新的机器中。这样,既不用全部重新哈希、搬移数据,也保持了各个机器上数据数量的均衡。

### 总结
# # 总结

在负载均衡应用中,利用哈希算法替代映射表,可以实现一个会话粘滞的负载均衡策略。在数据分片应用中,通过哈希算法对处理的海量数据进行分片,多机分布式处理,可以突破单机资源的限制。在分布式存储应用中,利用一致性哈希算法,可以解决缓存等分布式系统的扩容、缩容导致数据大量搬移的难题。

### 参考资料
# # 参考资料

[《数据结构与算法之美-王争》-哈希算法(下):哈希算法在分布式系统中有哪些应用?](https://time.geekbang.org/column/article/67388)

0 comments on commit 6dd7fa4

Please sign in to comment.