LeetCode 1049 最后一块石头的重量 II
题目链接:1049. 最后一块石头的重量 II - 力扣(LeetCode)
【解题思路】
-
尽量让两堆石头的重量相同,让留下的石头重量最小,这样,本题就可以抽象成01背包问题
-
1.确定dp数组以及下标的含义
-
dp[j]的定义为:装满容量为j的背包最大重量为dp[j]
-
-
3.确定dp数组如何初始化
-
dp[0]=0
-
意思是背包容量为0的时候,背包重量为0
-
-
非零下标应该初始化为非负数里的最小值,因为我们需要不断地进行比较,取最大值更新
-
-
5.举例推导dp数组
-
手动推导一下答案,然后将数组打印出来,看看每个状态是否是按照我们的思路进行转移的
-
-
dp[j] = max(dp[j],dp[j-stones[i]]+stones[i])
-
因为重量和价值都是nums[i]
-
-
两层for循环:
-
第一层遍历物品:
-
第二层遍历背包容量:
-
递推公式
-
-
-
-
注意:因为一维数组每一层的数据是需要重复利用的,因此遍历顺序只能是倒序遍历
-
我们需要倒序来保证每个物品添加一次,因为需要保证每个物品只添加一次,所以必须先遍历物品,再遍历背包
-
【解题步骤】
-
1.定义一个sum,统计当前数组总数
-
2.target = sum/2
-
3.初始化dp数组,大小为target+1
-
4.先遍历物品:
-
再遍历背包:
-
递推公式
-
-
-
5.返回 sum - 2*dp[target]
LeetCode 494 目标和
【解题思路】
-
根据题意,假设加法的总和为x,那么减法对应的集合就是sum-x
-
因此我们要求的是x-(sum-x) = target
-
可以写成x = (target+sum)/2
-
-
因此本题就是给我们一个背包的容量,问我们有多少种方式能把这个背包装满
-
1.确定dp数组以及下标的含义
-
dp[j]的定义为:装满容量为j的背包有dp[j]种方法
-
-
2.确定递推公式
-
dp[j] += dp[j-nums[i]]
-
-
3.确定dp数组如何初始化
-
dp[0]=1
-
意思装满容量为0的背包,有1种方法
-
-
因为我们当前下标的值是由前一个下标的值累加而成,因此不能将dp[0]初始化为0
-
-
4.确定遍历顺序
-
两层for循环:
-
第一层遍历物品:
-
第二层遍历背包容量:
-
递推公式
-
-
-
-
注意:因为一维数组每一层的数据是需要重复利用的,因此遍历顺序只能是倒序遍历
-
我们需要倒序来保证每个物品添加一次,因为需要保证每个物品只添加一次,所以必须先遍历物品,再遍历背包
-
-
-
5.举例推导dp数组
-
手动推导一下答案,然后将数组打印出来,看看每个状态是否是按照我们的思路进行转移的
-
【解题步骤】
-
1.定义一个sum,统计当前数组总数
-
2.如果target的绝对值大于sum,直接return 0;
-
3.如果target + sum除以2的余数不为0,直接return0;
-
4.背包容量 = (target+sum)/2
-
5.创建dp数组,初始化大小为背包长度+1
-
6.初始化dp[0] = 1
-
4.先遍历物品:
-
再遍历背包:
-
递推公式
-
-
-
5.返回dp[bagtargeyt]
LeetCode 474 一和零
【解题思路】
-
本题求的是装满这个背包最多有多少种物品
-
1.确定dp数组以及下标的含义
-
dp[i][j]的定义为:装满i个0,j个1的背包最多有多少种物品
-
最终要求的结果是dp[m][n]
-
-
2.确定递推公式
-
首先需要明确:
-
物品的重量为:多少个0和多少个1
-
背包的容量为:题目给出的m个0和n个1
-
-
dp[i][j] = max(dp[i][j],dp[i-x][j-y]+1)
-
-
3.确定dp数组如何初始化
-
dp[0][0]=0
-
意思背包容量为0时我们所装的物品种类数量为0
-
-
非零下标应该也初始成0,为了避免覆盖掉后面结果
-
-
4.确定遍历顺序
-
两层for循环:
-
第一层遍历物品(遍历字符串集合里的每一个字符串):
-
遍历字符串中的每一个字符:
-
将当前物品包含有多少个1,多少个0统计出来,也就是记录当前物品的重量
-
-
第二层遍历背包容量:
-
用两个for循环,遍历当前物品的0和1的个数
-
递推公式
-
-
-
-
注意:因为一维数组每一层的数据是需要重复利用的,因此遍历顺序只能是倒序遍历
-
我们需要倒序来保证每个物品添加一次,因为需要保证每个物品只添加一次,所以必须先遍历物品,再遍历背包
-
-
-
5.举例推导dp数组
-
手动推导一下答案,然后将数组打印出来,看看每个状态是否是按照我们的思路进行转移的
-
【解题步骤】
-
1.定义二维dp数组,大小初始化为m+1和n+1
-
2.定义x,y记录当前物品的01数量
-
3.遍历字符串数组(遍历物品):
-
1)将x,y初始化为0
-
目的是在每取出一个字符串时,都将xy计数器归0,重新统计0,1的个数
-
-
2)遍历当前字符串:
-
如果当前字符为0,则x++
-
如果当前字符为1,则y++
-
-
3)从i->x,遍历当前背包中0的数量:
-
从j->y,遍历当前背包中1的数量:
-
递推公式
-
-
-
-
4.返回dp[m][n]