Skip to content

Commit c9fa9a5

Browse files
coffe1891gitbook-bot
authored andcommitted
GitBook: [master] 68 pages modified
1 parent 72b5f52 commit c9fa9a5

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

2/2.1.7.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
### 解法一
1515

16+
问题其实是求从下标为`i``j`之间的连续数组项之和的最大值。
17+
1618
```javascript
1719
function fn(arr) {
1820
let maxSum=-Infinity, len = arr.length;
@@ -108,7 +110,7 @@ function fn(array) {
108110

109111
这是典型的动态规划问题。所谓动态规划,也即问题分成多个步骤,每一步的选择是可以动态调整的,所有步骤完成之后,最后求最优解。比如求两点之间的最优路径,多种组合方案的最优方案。**这类问题,可以分解成对每一步求最优解,然后将每步的最优解组合,即为最终最优解。**
110112

111-
本题求最少硬币数,也可以用动态规划法求解。首先要归纳出一个**状态转移方程**,求硬币数的函数f与金额i、硬币面值j之间的关系如下
113+
本题求最少硬币数,也可以用动态规划法求解。首先要归纳出一个**状态转移方程**给定的金额`i`,最少硬币数为`f(i)`,硬币面值为`j`,它们之间的关系可以用方程表达如下(该方程即为**状态转移方程**
112114

113115
$$
114116
f(i)=f(i-j)+1
@@ -118,8 +120,10 @@ $$
118120

119121
```javascript
120122
/**
121-
* 硬币找零 之 动态规划法
123+
* 硬币找零 之 动态规划法
122124
* 状态转移方程 DP(i)=DP(i-j)+1,其中i是金额,j是硬币面值。
125+
* @param {array} coins 硬币面额的数组
126+
* @param {number} amount 给定的金额数
123127
*/
124128

125129
(function (coins, amount) {
@@ -131,7 +135,7 @@ $$
131135
cache.set(coin, 1);
132136
});
133137

134-
let s = new Date().getTime();
138+
console.time("coffe1891");
135139

136140
let DP = function (amount) {
137141
if (amount <= 0)
@@ -157,11 +161,12 @@ $$
157161
}
158162
}
159163
console.log("从面值为 " + coins + " 的硬币中找零 " + amount + " 块钱,最少要 " + DP(amount) + " 枚硬币");
160-
let e = new Date().getTime();
161-
console.log("耗时 " + (e - s) + " ms");
164+
console.timeEnd('coffe1891');
162165
})([1, 2, 5, 10], 36);
163166
```
164167

168+
因此我们发现一个规律:**可用动态规划法解题的关键,在于找到状态转移方程,通过观察该方程,可以更快知道解题的具体算法思路**
169+
165170
### 解法二:贪心算法
166171

167172
每次我们都优先取最大的硬币面额,直到剩余金额不足最大面额时,我们会取第二大的面额,以此类推,从而实现总硬币数最小的目的。其思想非常简单,我们直接上代码:

0 commit comments

Comments
 (0)