DP(3) | 0-1背包 | Java | LeetCode 1049, 494, 474 做题总结(474未完)

1049. 最后一块石头的重量 II

和 LC 416.分割等和子集 类似

  • 思路(我没有思路):
    两块石头相撞,这里没有想到的一个点是,相撞的两个石头要几乎相似
    以示例1为例,stones = [2,7,4,1,8,1],如果从左到右相撞,得到的不是最优结果
    最优结果是相撞后重量最小的

    stones = [2,7,4,1,8,1],总和23,一半为11,把这组石头分为一组11 一组12,他们相撞就是1

    0-1背包,M个物品放入容量为N的背包中,物品价值value、重量weight

递归五步:

  1. 确定dp数组(dp table)以及下标的含义
    背包重量 j 最大价值 dp[j] 最大重量 dp[j]
  2. 确定递推公式
    价值: dp[j] = Math.max(dp[j], dp[j-weight[i]] +value[i])
    重量:dp[j] = Math.max(dp[j], dp[j-stones[i]] +stones[i])
  3. dp数组如何初始化
    dp[0] = 0,其余也都是0
    ② 由于题目定义 1 <= stones.length <= 30; 1 <= stones[i] <= 100 所以极端情况下每个元素都为100,共30个元素,sum = 3000 , half = 1500
    int[]dp = new int [1501]
  4. 确定遍历顺序
    for物品 { for背包 }
  5. 举例推导dp数组
    求得一组石头的重量是 a = dp[target] ,另一组为 b= sum-dp[target]
    这里 b-a一定大于零,因为sum/2是向下取整的
  • ac-二维数组版本
    写的时候出错:① 递推公式写错 ② 初始化行列不分 ③ 初始化的值应为固定的value[0]
    这道题目的二维数据版本空间内存消耗很多。
class Solution {public int lastStoneWeightII(int[] stones) {int sum = 0;for(int i=0; i<stones.length; i++) {sum += stones[i];}int bagSize = sum/2; // N// M = stones.lengthint[][] dp = new int[stones.length][bagSize+1]; //二维数组空间多很多//初始化第0行,物品0从哪里开始放for(int i=stones[0]; i<bagSize+1; i++) { // weight[0]dp[0][i] = stones[0];//value[0]错了}for(int i=1; i<stones.length; i++) {for(int j=1; j<bagSize+1; j++) {if(j<stones[i]) {dp[i][j] = dp[i-1][j];} else {dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-stones[i]] + stones[i] );}}}return sum-2*dp[stones.length-1][bagSize];}
}

在这里插入图片描述

  • ac-滚动数组版本
    写的过程中:递推公式又错了。
class Solution {public int lastStoneWeightII(int[] stones) {int sum = 0;for(int i=0; i<stones.length; i++) {sum += stones[i];}int bagSize = sum/2; // Nint M = stones.length; // Mint[] dp = new int[bagSize+1];for(int i=0; i<M; i++) {for(int j=bagSize; j>=stones[i]; j--) { // weight[i]//两种情况,要么放,要么不放dp[j] = Math.max(dp[j],dp[j-stones[i]]+stones[i]); // 1 weight 2 value}}return sum-2*dp[bagSize];}
}

494. 目标和

思路

准备两个背包,一个背包package_a存放标记为正的元素,另一个背包package_b存放标记为负的元素。package_a - package_b = target

设nums的元素和为sum, 可以列出方程:

package_a - package_b = target;
package_a + package_b = sum;

所以 package_a = (target + sum)/2。 所以根据题意给的target和sum,我们可以求出package_a的值。

那这道题就可以转化为:给定一个大小为package_a的背包,有多少种组合方式能把背包装满? 妥妥的0-1背包。

元素放或者不放

答案

class Solution {public int findTargetSumWays(int[] nums, int target) {int sum = 0;for(int i=0; i<nums.length; i++) {sum += nums[i];}        if(sum < Math.abs(target)){return 0;}if((sum + target) % 2 != 0) {return 0;}int bagSize = (target+sum)/2;int M = nums.length;int[][]dp = new int[M][bagSize+1];//首行-初始化if(nums[0] <= bagSize) {dp[0][nums[0]] = 1;}//首列-初始化int zeroNum = 0;for(int i=0; i<M; i++) {if(nums[i] == 0) {zeroNum++;}dp[i][0] = (int) Math.pow(2,zeroNum);// 有0的话,选或不选 2的x次方// 没有0,首列全部设为1??什么意思}for(int i=1; i<M; i++) {for(int j=1; j<bagSize+1; j++) {if(nums[i]>j) {dp[i][j] = dp[i-1][j];} else {dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]];}}}return dp[M-1][bagSize];}
}

难点

(1)错误状况 return 0的情况

  //如果target的绝对值大于sum,那么是没有方案的if (Math.abs(target) > sum) return 0;//如果(target+sum)除以2的余数不为0,也是没有方案的if ((target + sum) % 2 == 1) return 0;

(2)递推公式 dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]]的由来

在这里插入图片描述
(3)数组的初始化

  • 首行初始化:只初始化二维数组M*N里的一个格子,就是 j=nums[0] 时,也就是 只选 物品0,其余都不选,此时情况赋为1。
  if(nums[0] <= bagSize) {dp[0][nums[0]] = 1;}
  • 首列初始化:
    (1)数组元素有0的话,选或不选 2的x次方
    (2)数组元素没有0,首列全部设为1??什么意思
    dp[i][0] = 1,背包容量为0的时候,情况为1,或许可以理解为 这题本来就不是放背包,是求和??
    看到别人的解释:任何一个物品,只要选择不取的方案,就能凑成0容量的背包
	int zeroNum = 0;for(int i=0; i<M; i++) {if(nums[i] == 0) {zeroNum++;}dp[i][0] = (int) Math.pow(2,zeroNum);// (1)数组元素有0的话,选或不选 2的x次方// (2)数组元素没有0,首列全部设为1??什么意思// dp[i][0] = 1,背包容量为}

出错点

① Math.pow(); 之前要写 (int) 强制类型转换

Line 32: error: incompatible types: possible lossy conversion from double to intdp[i][0] = Math.pow(2,zeroNum);

打印dp(为了方便理解)

(1)

  int[]nums = {1,1,1,1,1};int target = 3;
  • 初始化

在这里插入图片描述

  • 最终dp

在这里插入图片描述

(2)打印

  int[]nums = {0,1,0,1,1};int target = 1;
  • 初始化

在这里插入图片描述

  • 最终dp

在这里插入图片描述

474.一和零

java

  • 除以 2 :int target = sum >> 1;

  • 强制类型转换:int x = (int)Math.pow(a, b); 意思是 a的b次方
    public static double pow(double 基数,double 幂次)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/45927.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Collections:专为集合框架而生的工具类

Collections 是 JDK 提供的一个工具类&#xff0c;位于 java.util 包下&#xff0c;提供了一系列的静态方法。 排序操作 reverse(List list)&#xff1a;反转顺序shuffle(List list)&#xff1a;洗牌&#xff0c;将顺序打乱sort(List list)&#xff1a;自然升序sort(List lis…

解答|服务器只能开22端口可以申请IP地址SSL证书吗?

IP地址SSL证书&#xff0c;是一种专门颁发给公网IP地址的SSL证书&#xff0c;而不是常见的基于域名的SSL证书。SSL证书主要用于保障数据在客户端&#xff08;如用户的浏览器&#xff09;和服务器之间传输时的加密性和安全性&#xff0c;以防止数据被截取或篡改。 服务器只能开…

github actions方式拉取docker镜像

参考&#xff1a; https://wkdaily.cpolar.cn/archives/gc 注意github actions提供的免费虚拟机空间有限&#xff0c;空间不足会报错&#xff0c;查看大概语句有10来G 我在workflow file里加了df -h 运行查看磁盘情况&#xff1a; 通过pwd命令&#xff0c;可以知道运行目录/ho…

ETL数据集成丨主流ETL工具(ETLCloud、DataX、Kettle)数据传输性能大PK

目前市面上的ETL工具众多&#xff0c;为了方便广大企业用户在选择ETL工具时有一个更直观性能方面的参考值&#xff0c;我们选取了目前市面上最流行的三款ETL工具&#xff08;ETLCloud、DataX、Kettle&#xff09;来作为本次性能传输的代表&#xff0c;虽然性能测试数据有很多相…

【JavaScript】解决 JavaScript 语言报错:Uncaught TypeError: XYZ is not a function

文章目录 一、背景介绍常见场景 二、报错信息解析三、常见原因分析1. 变量或对象属性类型错误2. 函数名拼写错误或覆盖3. 作用域问题导致的函数未定义4. 调用未初始化的函数 四、解决方案与预防措施1. 确保变量类型正确2. 检查拼写错误3. 注意作用域4. 初始化变量 五、示例代码…

C#中的反射

dll和exe文件的区别 用途&#xff1a; .exe&#xff08;可执行文件&#xff09;&#xff1a;是可以直接运行的程序文件。当你双击一个 .exe 文件或在命令行中输入它的名字&#xff0c;操作系统会加载并执行这个程序。 .dll&#xff08;动态链接库&#xff09;&#xff1a;包含…

graphviz subgraph添加边界框

subgraph name 属性必须要以cluster开头。 A Quick Introduction to GraphvizAn awesome tool for software documentation and visualizing graphshttps://www.worthe-it.co.za/blog/2017-09-19-quick-introduction-to-graphviz.html digraph {rankdir"LR"// the n…

【探索Linux】P.39(传输层 —— TCP的三次 “握手” 和四次 “挥手” )

阅读导航 引言一、TCP的三次握手1. 简介2. 图解三次握手3. 名词解释&#xff08;1&#xff09;SYN&#xff08;同步序列编号&#xff09;包&#xff08;2&#xff09;SYN-ACK&#xff08;同步确认&#xff09;包&#xff08;3&#xff09;ACK&#xff08;确认&#xff09;包 4.…

基于matlab的SVR回归模型

1 原理 SVR&#xff08;Support Vector Regression&#xff09;回归预测原理&#xff0c;基于支持向量机&#xff08;SVM&#xff09;的回归分支&#xff0c;其核心思想是通过寻找一个最优的超平面来进行回归预测&#xff0c;并处理非线性回归问题。以下是SVR回归预测原理的系统…

浪潮天启防火墙TQ2000远程配置方法SSL-V偏、L2xx 配置方法

前言 本次设置只针对配置V偏&#xff0c;其他防火墙配置不涉及。建议把防火墙内外网都调通后再进行V偏配置。 其他配置可参考&#xff1a;浪潮天启防火墙配置手册 配置SSLVxx 在外网端口开启SSLVxx信息 开启SSLVxx功能 1、勾选 “启用SSL-Vxx” 2、设置登录端口号&#xff0…

面试内容集合

用例设计方法 &#xff08;一&#xff09;等价类划分  常见的软件测试面试题划分等价类: 等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理…

智慧校园毕业管理:全面解读毕业批次功能

在智慧校园的毕业管理系统中&#xff0c;毕业批次模块通过其精心设计的毕业批次功能&#xff0c;为即将离校的学子们提供了一个高效、便捷的过渡平台。这一特色功能聚焦于特定时间段内的毕业生群体&#xff0c;巧妙融合数字技术&#xff0c;从信息核实到最终的离校程序&#xf…

代码随想录二刷7.22|977.有序数组的平方

暴力解法&#xff1a; ——如果想暴力解决这个问题的话&#xff0c;可以像题目那样&#xff0c;先将每一个元素平方&#xff0c;然后再排序 双指针&#xff1a; ——从题目中找到的信息&#xff1a;这是一个非递减顺序的整数数组&#xff0c;从例子中&#xff0c;可以容易看…

西邮计科嵌入式复习

西邮嵌入式复习 一、第一章复习二、第二章复习三、第三章复习四、第四章复习 一、第一章复习 二、第二章复习 三、第三章复习 四、第四章复习

内网服务器通过squid代理访问外网

一、背景 现在要对172.16.58.158服务器进行openssh升级操作,我用之前写好的升级脚本执行后,发现没有备份旧的ssh程序文件,然后还卸载了oenssl-devel,然后我发现其他服务器ssh该服务器失败。同时脚本执行时报错“ configure: error: *** zlib.h missing - please install first …

无人驾驶大热,新能源汽车智能化中的算网支持

来源新华社&#xff1a;百度“萝卜快跑”全无人驾驶汽车行驶在路上 当前&#xff0c;新能源汽车产业数智化已成为全球汽车产业数字化转型的焦点。一方面&#xff0c;随着人工智能、大数据、云计算等技术的深度融合&#xff0c;新能源汽车在自动驾驶、智能互联、能源管理等方面…

xmind梳理测试点,根据这些测试点去写测试用例

基本流&#xff08;冒烟用例必写&#xff09; 备选流 公共测试点&#xff1a;

【题解】42. 接雨水(动态规划 预处理)

https://leetcode.cn/problems/trapping-rain-water/description/ class Solution { public:int trap(vector<int>& height) {int n height.size();// 预处理数组vector<int> lefts(n, 0);vector<int> rights(n, 0);// 预处理记录左侧最大值lefts[0] …

GuLi商城-商品服务-API-品牌管理-OSS前后联调测试上传

服务端签名直传 这种方式文件上传不用走自己的服务器了 zhouyimo.oss-cn-beijing.aliyuncs.com 后端启动: nacos: 虚拟机启动:里面mysql自动启动 前端项目启动:npm run dev 单文件上传和多文件上传地址都要改成自己的外网访问地址

Minio搭建文件服务器的学习

MinIO是一个高性能的开源对象存储服务器&#xff0c;与Amazon S3兼容。它使用Go语言编写&#xff0c;可以在多种操作系统上运行&#xff0c;如Linux、MacOS和Windows等。MinIO的分布式特性使其能够轻松扩展存储容量和处理能力&#xff0c;满足大规模数据存储的需求。 使用Docke…