当前位置:网站首页>力扣记录:动态规划2背包问题(1)01背包——416 分割等和子集,1049 最后一块石头的重量II,494 目标和,474 一和零
力扣记录:动态规划2背包问题(1)01背包——416 分割等和子集,1049 最后一块石头的重量II,494 目标和,474 一和零
2022-07-21 05:16:00 【Kiwi_fruit】
本次题目
- 416 分割等和子集
- 1049 最后一块石头的重量II
- 494 目标和
- 474 一和零
01背包
- 01背包:容量为w的背包,n个物品,第i件物品的重量为weight[i],价值为value[i],每个物品只能装一次,求装哪些物品总价值最大。
- 二维dp数组01背包:
- 定义dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少;
- 递推公式当背包还能装下第i件物品时,dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
- 初始化dp[i][0] = 0,当背包容量j小于第0件物品重量weight[0]时,dp[0][j] = 0,否则dp[0][j] = value[0];
- 遍历顺序由小到大,这里先遍历物品再遍历背包;
- 举例。
- 一维滚动数组01背包:
- 定义一维数组d[j]表示上一层(i - 1)拷贝到当前层(i),即到物品i时放进容量为j的背包的最大总价值;
- 递推公式dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
- 物品由小到大,背包由大到小(由于上层覆盖当前层,防止同一物品被放多次);
- 遍历顺序只能先物品再背包;
- 举例。建议使用一维滚动数组。
416 分割等和子集
- 01背包DP:
- 定义dp[j]表示容量为j的背包,放入的数之和最大为dp[j],长度为目标和加1;
- 递推公式dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
- 初始化为全0(比物品价值小);
- 遍历顺序先遍历物品(由小到大)再遍历背包(由大到小);
- 举例。
class Solution {
public boolean canPartition(int[] nums) {
int leng = nums.length;
//判断特殊情况
if(leng == 1) return false;
//求目标值
int sum = 0;
for(int i = 0; i < leng; i++){
sum += nums[i];
}
//不是偶数返回false
if(sum % 2 == 1) return false;
int target = sum / 2;
//定义dp[j]表示容量为j的背包,放入的数之和最大为dp[j]
//长度为目标和加1
//初始化全0
int[] dp = new int[target + 1];
//遍历顺序先遍历物品(由小到大)再遍历背包(由大到小)
for(int i = 0; i < leng; i++){
for(int j = target; j >= nums[i]; j--){
dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
}
}
//返回结果
return dp[target] == target;
}
}
1049 最后一块石头的重量II
- 同上416 分割等和子集,将物品换位石头,还是将石头分为重量相同的两堆。
- 定义dp[j]表示容量为j的背包最多可以背重量为dp[j]的石头;
- 递推公式dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
- 将dp[0]初始化为0,长度为最大重量的一半;
- 遍历顺序先遍历物品(由小到大)再遍历背包(由大到小);
- 举例。
- 注意:取目标重量时向下取整,所以dp数组得到的重量较小。
class Solution {
public int lastStoneWeightII(int[] stones) {
//判断特殊情况
int leng = stones.length;
if(leng == 1) return stones[0];
int sum = 0;
for(int i = 0; i < leng; i++){
sum += stones[i];
}
int target = sum / 2;
//定义dp[j]表示容量为j的背包最多可以背重量为dp[j]的石头
//将dp[0]初始化为0,长度为最大重量的一半
int[] dp = new int[target + 1];
//遍历顺序先遍历物品(由小到大)再遍历背包(由大到小)
for(int i = 0; i < leng; i++){
for(int j = target; j >= stones[i]; j--){
dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
}
}
//返回结果
return sum - 2 * dp[target];
}
}
494 目标和
- 01背包DP(组合):
- 定义dp数组表示容量为j的背包装加法装满有dp[j]种方法;
- 递推公式dp[j] += dp[j - nums[i]];
- 初始化dp[0] = 1,长度为目标值加数组之和除以2(加1);
- 遍历顺序先物品(由小到大)再背包(由大到小);
- 举例。
- 注意:当目标数与数组之和不能被2整除时无结果。
class Solution {
public int findTargetSumWays(int[] nums, int target) {
//定义dp数组表示容量为j的背包装加法装满有dp[j]种方法
int sum = 0;
for(int i = 0; i < nums.length; i++) sum += nums[i];
//当目标数与数组之和不能被2整除时无结果。
if((sum + target) % 2 != 0) return 0;
int t = (sum + target) / 2;
//目标小于0时反过来
if(t < 0) t = -t;
int[] dp = new int[t + 1];
//初始化dp[0] = 1
dp[0] = 1;
//遍历顺序先物品(由小到大)再背包(由大到小)
for(int i = 0; i < nums.length; i++){
for(int j = t; j >= nums[i]; j--){
dp[j] += dp[j - nums[i]];
}
}
//返回结果
return dp[t];
}
}
474 一和零
- 01背包DP:
- 定义dp[i][j]表示:最多有i个0和j个1的strs的最大子集的大小为dp[i][j];
- 递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
- 初始化dp[0] = 0;
- 遍历顺序先物品(由小到大)再背包(二维,由大到小);
- 举例。
class Solution {
public int findMaxForm(String[] strs, int m, int n) {
//定义dp[i][j]表示:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]
int[][] dp = new int[m + 1][n + 1];
//统计字符串种0和1个数
for(String str : strs){
int zeroNum = 0;
int oneNum = 0;
char[] s_arr = str.toCharArray();
for(char s : s_arr){
if(s == '1'){
oneNum += 1;
}else{
zeroNum += 1;
}
}
//遍历顺序先物品(由小到大)再背包(二维,由大到小)
for(int i = m; i >= zeroNum; i--){
for(int j = n; j >= oneNum; j--){
dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
}
}
}
//返回结果
return dp[m][n];
}
}
边栏推荐
- Principles and advantages of wireless charging module development
- 74. 搜索二维矩阵
- 每日升个级
- 取石子
- 110. Balanced binary tree
- 029: Tao Tao picks apples
- 西瓜书第二章笔记-性能度量
- The evolution of data warehouse in recent 10 years and suggestions on database learning
- Heap - principle to application - heap sorting, priority queue
- 2021普及组总结
猜你喜欢
How to complete the design of RGB lamp Bluetooth mesh module from 0 to 1
表达式求值
567. Arrangement of strings
Heap - principle to application - heap sorting, priority queue
Upgrade every day
2021普及组总结
Characteristics and differences between PCB and integrated circuit
What is the difference between embedded hardware and software in embedded development?
Principles and advantages of wireless charging module development
108. 将有序数组转换为二叉搜索树
随机推荐
Property analysis of matter protocol (II) multiple fabric and permission control
数据可视化应用安装部署 | 使用 datart 安装包和源码部署的常见问题教程
Built in WiFi and Bluetooth chip of Flathead brother xuantie
Mapping between sets and potential of sets
XML详解
完成mysql数据库主从复制集群的搭建教程
Subsequence
表达式求值
堪比“神仙打架”的开源数据可视化社群,你见过吗?
Take stones
2022ACM夏季集训周报(一)
19. 删除链表的倒数第 N 个结点
005: storage space size of integer data type
P1111 修复公路(并查集)
如何用数组模拟栈(超简易代码)
西瓜书第二章-比较检验
QT初学者
543. 二叉树的直径
567. Arrangement of strings
844. 比较含退格的字符串