mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-11 21:10:58 +08:00
Merge pull request #959 from gaoyangu/master
修改 279.完全平方中 i 和 j 的错误使用 和 动态规划背包问题系列中的部分笔误
This commit is contained in:
@ -220,7 +220,7 @@ public:
|
|||||||
|
|
||||||
但因为分割子串的特殊性,遍历背包放在外循环,将遍历物品放在内循环更方便一些。
|
但因为分割子串的特殊性,遍历背包放在外循环,将遍历物品放在内循环更方便一些。
|
||||||
|
|
||||||
本题其实递推公式都不是重点,遍历顺序才是重点,如果我直接把代码贴出来,估计同学们也会想两个for循环的顺序理所当然就是这样,甚至都不会想为什么遍历背包的for循环为什么在外层。
|
本题其实递推公式都不是重点,遍历顺序才是重点,如果我直接把代码贴出来,估计同学们也会想两个for循环的顺序理所当然就是这样,甚至都不会想为什么遍历背包的for循环在外层。
|
||||||
|
|
||||||
不分析透彻不是Carl的风格啊,哈哈
|
不分析透彻不是Carl的风格啊,哈哈
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
1. 确定dp数组(dp table)以及下标的含义
|
1. 确定dp数组(dp table)以及下标的含义
|
||||||
|
|
||||||
**dp[i]:和为i的完全平方数的最少数量为dp[i]**
|
**dp[j]:和为j的完全平方数的最少数量为dp[j]**
|
||||||
|
|
||||||
2. 确定递推公式
|
2. 确定递推公式
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ dp[0]表示 和为0的完全平方数的最小数量,那么dp[0]一定是0。
|
|||||||
|
|
||||||
非0下标的dp[j]应该是多少呢?
|
非0下标的dp[j]应该是多少呢?
|
||||||
|
|
||||||
从递归公式dp[j] = min(dp[j - i * i] + 1, dp[j]);中可以看出每次dp[j]都要选最小的,**所以非0下标的dp[i]一定要初始为最大值,这样dp[j]在递推的时候才不会被初始值覆盖**。
|
从递归公式dp[j] = min(dp[j - i * i] + 1, dp[j]);中可以看出每次dp[j]都要选最小的,**所以非0下标的dp[j]一定要初始为最大值,这样dp[j]在递推的时候才不会被初始值覆盖**。
|
||||||
|
|
||||||
4. 确定遍历顺序
|
4. 确定遍历顺序
|
||||||
|
|
||||||
@ -70,9 +70,9 @@ dp[0]表示 和为0的完全平方数的最小数量,那么dp[0]一定是0。
|
|||||||
|
|
||||||
在[动态规划:322. 零钱兑换](https://programmercarl.com/0322.零钱兑换.html)中我们就深入探讨了这个问题,本题也是一样的,是求最小数!
|
在[动态规划:322. 零钱兑换](https://programmercarl.com/0322.零钱兑换.html)中我们就深入探讨了这个问题,本题也是一样的,是求最小数!
|
||||||
|
|
||||||
**所以本题外层for遍历背包,里层for遍历物品,还是外层for遍历物品,内层for遍历背包,都是可以的!**
|
**所以本题外层for遍历背包,内层for遍历物品,还是外层for遍历物品,内层for遍历背包,都是可以的!**
|
||||||
|
|
||||||
我这里先给出外层遍历背包,里层遍历物品的代码:
|
我这里先给出外层遍历背包,内层遍历物品的代码:
|
||||||
|
|
||||||
```CPP
|
```CPP
|
||||||
vector<int> dp(n + 1, INT_MAX);
|
vector<int> dp(n + 1, INT_MAX);
|
||||||
|
@ -81,7 +81,7 @@ dp[0] = 0;
|
|||||||
|
|
||||||
4. 确定遍历顺序
|
4. 确定遍历顺序
|
||||||
|
|
||||||
本题求钱币最小个数,**那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数。**。
|
本题求钱币最小个数,**那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数**。
|
||||||
|
|
||||||
所以本题并不强调集合是组合还是排列。
|
所以本题并不强调集合是组合还是排列。
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ public:
|
|||||||
|
|
||||||
这也是我为什么要先讲518.零钱兑换II 然后再讲本题即:322.零钱兑换,这是Carl的良苦用心那。
|
这也是我为什么要先讲518.零钱兑换II 然后再讲本题即:322.零钱兑换,这是Carl的良苦用心那。
|
||||||
|
|
||||||
相信大家看完之后,对背包问题中的遍历顺序又了更深的理解了。
|
相信大家看完之后,对背包问题中的遍历顺序有更深的理解了。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public:
|
|||||||
|
|
||||||
关键看遍历顺序。
|
关键看遍历顺序。
|
||||||
|
|
||||||
本题求钱币最小个数,**那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数。**。
|
本题求钱币最小个数,**那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数**。
|
||||||
|
|
||||||
所以本题并不强调集合是组合还是排列。
|
所以本题并不强调集合是组合还是排列。
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
## 周一
|
## 周一
|
||||||
|
|
||||||
[动态规划:开始打家劫舍!](https://programmercarl.com/0198.打家劫舍.html)中就是给一个数组相邻之间不能连着偷,如果偷才能得到最大金钱。
|
[动态规划:开始打家劫舍!](https://programmercarl.com/0198.打家劫舍.html)中就是给一个数组相邻之间不能连着偷,如何偷才能得到最大金钱。
|
||||||
|
|
||||||
1. 确定dp数组含义
|
1. 确定dp数组含义
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ dp[1] = max(nums[0], nums[1]);
|
|||||||
|
|
||||||
## 周三
|
## 周三
|
||||||
|
|
||||||
[动态规划:还要打家劫舍!](https://programmercarl.com/0337.打家劫舍III.html)这次是在一颗二叉树上打家劫舍了,条件还是一样的,相临的不能偷。
|
[动态规划:还要打家劫舍!](https://programmercarl.com/0337.打家劫舍III.html)这次是在一棵二叉树上打家劫舍了,条件还是一样的,相临的不能偷。
|
||||||
|
|
||||||
这道题目是树形DP的入门题目,其实树形DP其实就是在树上进行递推公式的推导,没有什么神秘的。
|
这道题目是树形DP的入门题目,其实树形DP其实就是在树上进行递推公式的推导,没有什么神秘的。
|
||||||
|
|
||||||
@ -191,12 +191,12 @@ return {val2, val1};
|
|||||||
|
|
||||||
## 周四
|
## 周四
|
||||||
|
|
||||||
[动态规划:买卖股票的最佳时机](https://programmercarl.com/0121.买卖股票的最佳时机.html) 一段时间,只能买买一次,问最大收益。
|
[动态规划:买卖股票的最佳时机](https://programmercarl.com/0121.买卖股票的最佳时机.html) 一段时间,只能买卖一次,问最大收益。
|
||||||
|
|
||||||
这里我给出了三中解法:
|
这里我给出了三种解法:
|
||||||
|
|
||||||
暴力解法代码:
|
暴力解法代码:
|
||||||
```
|
```CPP
|
||||||
class Solution {
|
class Solution {
|
||||||
public:
|
public:
|
||||||
int maxProfit(vector<int>& prices) {
|
int maxProfit(vector<int>& prices) {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
# 动态规划:关于多重背包,你该了解这些!
|
# 动态规划:关于多重背包,你该了解这些!
|
||||||
|
|
||||||
之前我们已经体统的讲解了01背包和完全背包,如果没有看过的录友,建议先把如下三篇文章仔细阅读一波。
|
之前我们已经系统的讲解了01背包和完全背包,如果没有看过的录友,建议先把如下三篇文章仔细阅读一波。
|
||||||
|
|
||||||
* [动态规划:关于01背包问题,你该了解这些!](https://programmercarl.com/背包理论基础01背包-1.html)
|
* [动态规划:关于01背包问题,你该了解这些!](https://programmercarl.com/背包理论基础01背包-1.html)
|
||||||
* [动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://programmercarl.com/背包理论基础01背包-2.html)
|
* [动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://programmercarl.com/背包理论基础01背包-2.html)
|
||||||
|
@ -177,41 +177,41 @@ int main() {
|
|||||||
Java:
|
Java:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
//先遍历物品,再遍历背包
|
//先遍历物品,再遍历背包
|
||||||
private static void testCompletePack(){
|
private static void testCompletePack(){
|
||||||
int[] weight = {1, 3, 4};
|
int[] weight = {1, 3, 4};
|
||||||
int[] value = {15, 20, 30};
|
int[] value = {15, 20, 30};
|
||||||
int bagWeight = 4;
|
int bagWeight = 4;
|
||||||
int[] dp = new int[bagWeight + 1];
|
int[] dp = new int[bagWeight + 1];
|
||||||
for (int i = 0; i < weight.length; i++){
|
for (int i = 0; i < weight.length; i++){
|
||||||
for (int j = 1; j <= bagWeight; j++){
|
for (int j = 1; j <= bagWeight; j++){
|
||||||
if (j - weight[i] >= 0){
|
if (j - weight[i] >= 0){
|
||||||
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
|
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int maxValue : dp){
|
|
||||||
System.out.println(maxValue + " ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for (int maxValue : dp){
|
||||||
|
System.out.println(maxValue + " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//先遍历背包,再遍历物品
|
//先遍历背包,再遍历物品
|
||||||
private static void testCompletePackAnotherWay(){
|
private static void testCompletePackAnotherWay(){
|
||||||
int[] weight = {1, 3, 4};
|
int[] weight = {1, 3, 4};
|
||||||
int[] value = {15, 20, 30};
|
int[] value = {15, 20, 30};
|
||||||
int bagWeight = 4;
|
int bagWeight = 4;
|
||||||
int[] dp = new int[bagWeight + 1];
|
int[] dp = new int[bagWeight + 1];
|
||||||
for (int i = 1; i <= bagWeight; i++){
|
for (int i = 1; i <= bagWeight; i++){
|
||||||
for (int j = 0; j < weight.length; j++){
|
for (int j = 0; j < weight.length; j++){
|
||||||
if (i - weight[j] >= 0){
|
if (i - weight[j] >= 0){
|
||||||
dp[i] = Math.max(dp[i], dp[i - weight[j]] + value[j]);
|
dp[i] = Math.max(dp[i], dp[i - weight[j]] + value[j]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int maxValue : dp){
|
|
||||||
System.out.println(maxValue + " ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for (int maxValue : dp){
|
||||||
|
System.out.println(maxValue + " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user