|
9 | 9 |
|
10 | 10 | 
|
11 | 11 |
|
12 | | -**通知:[新版网站会员](https://labuladong.online/algo/intro/site-vip/) 限时优惠;算法可视化编辑器上线,[点击体验](https://labuladong.online/algo/intro/visualize/)!另外,建议你在我的 [网站](https://labuladong.online/algo/) 学习文章,体验更好。** |
| 12 | +**通知:[新版网站会员](https://labuladong.online/algo/intro/site-vip/) 即将涨价!算法可视化编辑器上线,[点击体验](https://labuladong.online/algo/intro/visualize/)!另外,建议你在我的 [网站](https://labuladong.online/algo/) 学习文章,体验更好。** |
13 | 13 |
|
14 | 14 |
|
15 | 15 |
|
|
47 | 47 |
|
48 | 48 | 以上提到的重叠子问题、最优子结构、状态转移方程就是动态规划三要素。具体什么意思等会会举例详解,但是在实际的算法问题中,写出状态转移方程是最困难的,这也就是为什么很多朋友觉得动态规划问题困难的原因,我来提供我总结的一个思维框架,辅助你思考状态转移方程:
|
49 | 49 |
|
50 | | -**明确 base case -> 明确「状态」-> 明确「选择」 -> 定义 `dp` 数组/函数的含义**。 |
| 50 | +**明确「状态」-> 明确「选择」 -> 定义 `dp` 数组/函数的含义**。 |
51 | 51 |
|
52 | 52 | 按上面的套路走,最后的解法代码就会是如下的框架:
|
53 | 53 |
|
@@ -281,16 +281,16 @@ int coinChange(int[] coins, int amount);
|
281 | 281 |
|
282 | 282 | 那么,既然知道了这是个动态规划问题,就要思考如何列出正确的状态转移方程?
|
283 | 283 |
|
284 | | -**1、确定 base case**,这个很简单,显然目标金额 `amount` 为 0 时算法返回 0,因为不需要任何硬币就已经凑出目标金额了。 |
| 284 | +**1、确定「状态」,也就是原问题和子问题中会变化的变量**。由于硬币数量无限,硬币的面额也是题目给定的,只有目标金额会不断地向 base case 靠近,所以唯一的「状态」就是目标金额 `amount`。 |
285 | 285 |
|
286 | | -**2、确定「状态」,也就是原问题和子问题中会变化的变量**。由于硬币数量无限,硬币的面额也是题目给定的,只有目标金额会不断地向 base case 靠近,所以唯一的「状态」就是目标金额 `amount`。 |
| 286 | +**2、确定「选择」,也就是导致「状态」产生变化的行为**。目标金额为什么变化呢,因为你在选择硬币,你每选择一枚硬币,就相当于减少了目标金额。所以说所有硬币的面值,就是你的「选择」。 |
287 | 287 |
|
288 | | -**3、确定「选择」,也就是导致「状态」产生变化的行为**。目标金额为什么变化呢,因为你在选择硬币,你每选择一枚硬币,就相当于减少了目标金额。所以说所有硬币的面值,就是你的「选择」。 |
289 | | - |
290 | | -**4、明确 `dp` 函数/数组的定义**。我们这里讲的是自顶向下的解法,所以会有一个递归的 `dp` 函数,一般来说函数的参数就是状态转移中会变化的量,也就是上面说到的「状态」;函数的返回值就是题目要求我们计算的量。就本题来说,状态只有一个,即「目标金额」,题目要求我们计算凑出目标金额所需的最少硬币数量。 |
| 288 | +**3、明确 `dp` 函数/数组的定义**。我们这里讲的是自顶向下的解法,所以会有一个递归的 `dp` 函数,一般来说函数的参数就是状态转移中会变化的量,也就是上面说到的「状态」;函数的返回值就是题目要求我们计算的量。就本题来说,状态只有一个,即「目标金额」,题目要求我们计算凑出目标金额所需的最少硬币数量。 |
291 | 289 |
|
292 | 290 | **所以我们可以这样定义 `dp` 函数:`dp(n)` 表示,输入一个目标金额 `n`,返回凑出目标金额 `n` 所需的最少硬币数量**。
|
293 | 291 |
|
| 292 | +那么根据这个定义,我们的最终答案就是 `dp(amount)` 的返回值。 |
| 293 | + |
294 | 294 | 搞清楚上面这几个关键点,解法的伪码就可以写出来了:
|
295 | 295 |
|
296 | 296 | <!-- muliti_language -->
|
|
0 commit comments