【力扣一刷】代码随想录day43(动态规划part5 - 背包问题专题: 1049. 最后一块石头的重量II、494. 目标和、474.一和零)

【1049. 最后一块石头的重量 II】中等题

思路:要学会将问题转化为01背包问题求解(我还是不会转换,看了卡哥的思路才会)

题意要求的是【粉碎后最小的可能重量】,想象一下,如果尽可能地将这堆石头分成重量最接近的两堆石头,即达到两边重量最可能平衡的状态,那么这个重量的差值就是题意要求解的最小可能重量。需要两堆石头重量最接近,相当于求容量为sum/2的书包能产生的最大价值,此时对应两堆石头最可能平衡时的重量差。


例子1:输入:stones = [2,7,4,1,8,1]   输出:1

sum = 23,target = 23 / 2 = 11,不可能将这堆石头恰好分成重量相同的两堆,但是最理想的情况下,是容量为11的背包恰好能装满,那么背包里的石头的重量就是11,剩下的没被装入书包的石头的重量就是23-11=12,那么两堆石头的重量差值就是12-11=1,即和为奇数的数组的最小差值至少为1。


例子2:输入:stones = [1,2,2,1]   输出:0

sum = 6,target = 6 / 2 = 3,有可能将这堆石头分为重量相等的两堆,最理想的情况下,是容量为3的书包恰好能装满,那么背包里的石头的重量就是3,剩下没装入书包的石头重量也是3,则重量的差值就是0,即和为偶数的数组的最小差值至少为0。


例子3:输入:stones = [31,26,33,21,40]  输出:5

sum=151,target = 151 / 2 = 75,容量为75的书包最多能装重量为73的石头,那么剩下的石头的重量为151 - 73 = 78,那么最小差值就是 78 - 72 = 5。


步骤:

1、计算总和
2、计算目标容量
3、初始化数组
4、进行递推:

在容量足够的情况下,能考虑放/不放
剪枝(可不写):如果容量为target书包早就满了,直接返回差值即可
5、返回最小差值

class Solution {
    public int lastStoneWeightII(int[] stones) {
        // 1、计算总和
        int sum = 0;
        for(int stone : stones) sum += stone;
        // 2、计算目标容量
        int target = sum / 2;
        // 3、初始化数组
        int[] dp = new int[target+1];
        // 4、进行递推
        for (int i = 0; i < stones.length; i++){
            for (int j = target; j >= stones[i]; j--){ // 容量必须倒序遍历,j >= stones[i]确保足够容量放下i
                dp[j] = Math.max(dp[j], dp[j-stones[i]] + stones[i]); // 在容量足够的情况下,能考虑放/不放
            }
            // 剪枝(可不写):如果容量为target书包早就满了,直接返回差值即可
            if (dp[target] == target) return sum % 2 == 0? 0 : 1; //不能直接返回0,如果sum是奇数,差值为1
        }
        // dp[target]是最平衡的情况下其中一边的重量,另一边的重量是sum - dp[target],返回最小差值
        return (sum - dp[target]) - dp[target];
    }
}
  • 时间复杂度:O(M×N)
  • 空间复杂度:O(N)

【494. 目标和】中等题(用数学推导,得多刷几次)

思路:将问题转化为01背包问题求解

根据题意,要为数组中的每个元素加上符号,求使表达式的值为target的方案数。

如果将数组的元素按符号进行分类,即将一部分看作正数分到数组pos中,剩下的看作负数分到数组neg中,出现 posSum - negSum = target 时这个方案成立。

理想情况下,

posSum + negSum = sum  (1)

posSum - negSum = target  (2)

将(1)+(2)得,posSum = (sum + target) / 2

即如果数组中存在多个元素的和(posSum)等于(sum+target) / 2的情况,则统计共有多少种这样的情况,即得到题目要求的方案数。那么,现在的问题就转换为,求恰好能将容量为(sum+target) / 2的书包装满的方案数 / 元素组合数。

易错点:不能直接将dp[j]定义为容量为 j 的书包产生的最大价值,因为像下面代码那样,只在恰好将容量为posNum装满时次数加1,会忽略前面未装满情况下的组合情况,导致次数少于正确的结果次数。因此,dp[j]应该定义为【恰好装满】容量为 j 的书包的【方案数】。

for (int i = 0; i < nums.length; i++){
    for (int j = posSum; j >= nums[i]; j--){
        int pre = dp[j];
        dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
        if (j == posSum && dp[posSum] == posSum){ // 如果出现posSum容量的书包已满,判断是否是新的方案,是则+1
            if (pre <= dp[j - nums[i]] + nums[i]) cnt++;
        }
    }
}

优化:

1、如果 target > sum,则不可能实现,方案数为0

2、如果 sum + target 为奇数,则不可能实现,方案数为0,因为需要容量恰好为 (sum + target) % 2 为奇数时,sum + target 除以2的真实值为小数,多个整数元素之和不可能为小数,例如sum + target = 7, (sum + target) * 1.0/ 2 = 3.5,需要元素之和为3.5才能使最后的表达式的值为target,但数组中的元素都是整数,不可能实现,因此方案数一定会为0。

3、如果posSum为负数,而元素之和不可能为负数,则方案数一定为0。


难点:

dp[j]代表的是恰好把容量为 j 的书包装满的方案数,而不是最大价值,如何确定递推关系?

方案:

对于0~ i 的元素,恰好装满容量为 j 的书包的方案数 = 没有nums[i]时恰好装满容量为 j 的书包的方案数(dp[j]) + 有nums[i]时恰好装满容量为 j - numms[i] 的书包的方案数(dp[j-nums[i]])。

重点:理解为什么一定包含第 i 个物品且恰好装满的方案数为dp[j - nums[i]]?

因为肯定包含第 i 个物品,所以需要为第 i 个物品腾出 nums[i] 大小的空间,则背包的容量就变成 j - nums[i],问题转换为将容量为 j - nums[i] 的书包恰好装满的方案数,即 dp[j - nums[i]]。

注意:

dp[0]应该初始化为1,即恰好装满容量为0的书包的方案数为1,即不装,否则后面计算的所有数值都是0。

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        for (int num : nums) sum += num;
        if (target > sum) return 0;
        if ((sum + target) % 2 != 0) return 0;
        int posSum = (sum + target) / 2;
        if (posSum < 0) return 0; // 元素值都>=0,求和不可能为负数,如果目标和为负数,直接返回0即可

        int dp[] = new int[posSum + 1];
        int cnt = 0;
        dp[0] = 1; // j = 0,书包容量为0,不放或者如果第一个元素刚好是0,则只有放这个方案
        for (int i = 0; i < nums.length; i++){
            for (int j = posSum; j >= nums[i]; j--){
                // 没有nums[i]时和为j的方案数(dp[j]) + 有nums[i]时和为j-numms[i]的方案数(dp[j-nums[i]])
                dp[j] += dp[j-nums[i]]; 
            }
        }
        return dp[posSum];
    }
}
  • 时间复杂度:O(M×N)
  • 空间复杂度:O(N)

【474.一和零】中等题

思路:

1、确定dp[i][j]的含义:

容量有两个维度,m和n,m是0的个数,n是1的个数,dp[i][j]表示最多有m个0和n个1的最大子集长度

2、确定递推关系:

不加第i个元素的最大子集长度 vs 加上第i个元素的最大子集长度,取长的作为答案。

3、确定初始值:

没有遍历字符串前,最大子集长度都是0即可

(难点:只是将一维滚动数组变成了二维滚动数组)

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        // dp[i][j] -> 表示最多有m个0和n个1的最大子集长度
        int dp[][] = new int[m+1][n+1]; // 容量有两个维度,m和n,m是0的个数,n是1的个数
        for (String str : strs){
            // 计算当前字符串的0和1个数
            int cnt0 = 0;
            for (char c : str.toCharArray()){
                if (c == '0') cnt0++;
            }
            int cnt1 = str.length() - cnt0; // 不是0就是1,总长度-0的个数 = 1的个数

            // 滚动更新二维数组
            for (int i = m; i >= cnt0; i--){
                for (int j = n; j >= cnt1; j--){
                    // 不加第i个元素的最大子集长度 vs 加上第i个元素的最大子集长度,取长的作为答案
                    dp[i][j] = Math.max(dp[i][j], dp[i - cnt0][j - cnt1] + 1);
                }
            }
        }
        return dp[m][n];
    }
}
  • 时间复杂度:O(K×M×N),K指数组的长度
  • 空间复杂度:O(M×N)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法课程笔记——如何倍增

快速幂 读入量大于1e5不要用cin读入&#xff0c;要用也要关闭同步流 第i个o次方的父亲 #include<bits/stdc.h>usingnamespacestd; #definemaxn 110000#definell long longintn, a[maxn], f[maxn][40]; intquery(intl, intr){intk (int)(log((r - l 1) * 1.0) / log(2.0…

从OutputStream类看Java中的IO流操作

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

一般显卡3d建模渲染够用吗?3d云渲染助力

3D建模和渲染对计算机硬件有较高要求&#xff0c;特别是显卡。显卡的性能直接影响渲染速度&#xff0c;低端和高端显卡在渲染效率上存在显著差异。对于追求快速渲染的用户&#xff0c;高端显卡是首选。那么&#xff0c;4050显卡是否能够满足3D建模渲染的需求呢?下面我们来探讨…

CSS悬浮动画

<button class"btn">悬浮动画</button>.btn {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);padding: 10px 20px;width: 200px;height: 50px;background-color: transparent;border-radius: 5px;border: 2px solid powderblu…

第78天:WAF攻防-菜刀冰蝎哥斯拉流量通讯特征绕过检测反制感知

目录 案例一&#xff1a; 菜刀-流量&绕过&特征&检测 菜刀的流量特征 案例二&#xff1a;冰蝎-流量&绕过&特征&检测 冰蝎使用教程 冰蝎的流量特征 案例三&#xff1a; 哥斯拉-流量&绕过&特征&检测 哥斯拉使用教程 哥斯拉的流量特征…

二手车买卖求购置换租车微信抖音小程序开源版开发

二手车买卖求购置换租车微信抖音小程序开源版开发 二手车置换平台小程序系统&#xff0c;为买家和卖家提供了一个交流和交易的平台 Uniapp&#xff0c;基于Uniapp开发&#xff0c;仅支持编译微信小程序和抖音小程序 车辆发布&#xff0c;自主发布车辆信息。 圈子交流&#xff…

自动驾驶主流芯片及平台架构(二)特斯拉自动驾驶芯片平台介绍

早期 对外采购mobileye EyeQ3 芯片摄像头半集成方案&#xff0c;主要是为了满足快速量产需求&#xff0c;且受制于研发资金不足限制&#xff1b; 中期 采用高算力NVIDIA 芯片平台其他摄像头供应商的特斯拉内部集成方案&#xff0c;mobileye开发节奏无法紧跟特斯拉需求&#xff…

嵌入式系统应用-拓展-FLASH之操作 SFUD (Serial Flash Universal Driver)之KEIL移植

1 SFUD介绍 1.1 初步介绍 SFUD 是一个开源的串行 SPI 闪存通用驱动库。由于市面上有各种类型的串行闪存设备&#xff0c;每种设备都具有不同的规格和指令&#xff0c;因此 SFUD 的设计目的是解决这些差异。这使得我们的产品可以支持不同品牌和规格的闪存&#xff0c;增强了软…

任意文件读取rce记录

1.跨目录上传 对某系统进行测试时&#xff0c;发现有一处上传附件的功能&#xff0c;常规上传个文件试试 发现返回包返回了重命名后的文件名称和系统的绝对路径 继续看上传的文件 只有一个预览的功能&#xff0c;访问直接下载该文件&#xff0c;并没有什么用&#xff0c;请求链…

Ansible自动化运维工具单模块介绍

前言 自动化运维是指利用自动化工具和技术来简化、自动化和优化IT基础设施的管理和运维过程&#xff0c;从而提高效率、降低成本&#xff0c;并减少人为错误。在当今复杂的IT环境中&#xff0c;自动化运维已经成为许多组织和企业提高生产力和保证系统稳定性的重要手段。Ansibl…

NYU Depth V2数据集相关介绍

一、参考资料 NYU Depth Dataset V2官网 论文&#xff1a;Indoor Segmentation and Support Inference from RGBD Images 二、 相关介绍 1.简介 NYU-Depth V2数据集由来自微软 Kinect 的RGB和深度相机记录的各种室内场景的视频序列组成。它具有&#xff1a; 1449对密集标…

Transformer全流程细致讲解

文章目录 1. Transformer 架构概述2. 编码器&#xff08;Encoder&#xff09;2.1 输入嵌入层&#xff08;Input Embedding Layer&#xff09;2.1.1 一个简单的示例 2.2 位置编码&#xff08;Positional Encoding&#xff09;2.2.1 Transformer中采用的位置编码方式2.2.2 公式中…

个人直播/流媒体服务解决方案实践

目录 1. 说明 1.1 拓扑结构图 2. 准备工作 2.1 软硬件清单 3. 步骤 3.1 按上面的软硬件清单准备好材料 3.2 内网检查测试 3.3 透传到公网服务器 3.5 机顶盒配置 4. 总结 5. 参考 6. 后语 1. 说明 - 在本地局域网建立流媒体服务&#xff0c;并发布到公网服务器供终…

【CTF Web】XCTF GFSJ0482 weak_auth Writeup(弱口令+密码爆破)

weak_auth 小宁写了一个登陆验证页面&#xff0c;随手就设了一个密码。 解法 随便输入一些字符&#xff0c;提示以 admin 登录。 使用 Burp 抓包。 导入密码字典。 进行爆破。 得到密码。 账号&#xff1a;admin 密码&#xff1a;123456取得 flag。 Flag cyberpeace{42c9664…

(论文阅读-多目标优化器)Multi-Objective Parametric Query Optimization

目录 摘要 一、简介 1.1 State-of-the-Art 1.2 贡献和大纲 二、定义 三、相关工作 四、问题分析 4.1 分析 4.2 算法设计影响 五、通用算法 5.1 算法概述 5.2 完备性证明 六、分段线性代价函数算法 6.1 数据结构 6.2 基本运算实现 6.3 复杂度分析 七、实验评估 …

数据库大作业——基于qt开发的图书管理系统(二) 相关表结构的设计

前言 在上一篇文章中。我们完成了Qt环境的安装&#xff0c;同时完成了有关项目需求的分析并绘制了整体的项目架构图&#xff0c;而在图书管理系统中&#xff0c;其实我们主要完成的就是对数据的增删改查&#xff0c;并将这些功能通过信号与槽机制和可视化界面绑定在一起&#…

【菜单下拉效果】基于jquery实现二级菜单下拉效果(附完整源码下载)

Js菜单下拉特效目录 &#x1f354;涉及知识&#x1f964;写在前面实现效果&#x1f367;一、涉及知识&#x1f333;二、具体实现2.1 搭建一级菜单2.2 搭建二级菜单项2.3 引入js文件2.4 构建CSS文件 &#x1f40b;三、源码获取&#x1f305; 作者寄语 &#x1f354;涉及知识 ht…

Xinstall实操指南:二维码推广,轻松追踪App安装效果!

在移动互联网时代&#xff0c;App的推广方式层出不穷&#xff0c;但二维码推广始终占据着重要的地位。作为国内专业的App全渠道统计服务商&#xff0c;Xinstall深知二维码推广的潜力与价值&#xff0c;并致力于通过创新的技术和服务&#xff0c;帮助广告主和开发者实现推广效果…

AtCoder Regular Contest 176(ARC176)A、B

题目&#xff1a;AtCoder Regular Contest 176 - tasks 官方题解&#xff1a;AtCoder Regular Contest 176 - editorial 参考&#xff1a;atcoder regular 176 (ARC176) A、B题解 A - 01 Matrix Again 题意 给一个nn的方格&#xff0c;给出m个坐标(x,y)m&#xff0c;在方格中…

opencv图像处理详细讲

传统的计算机视觉框架&#xff1a; SimpleCV BoofCV Dlib JavaCV 深度学习计算机视觉框架 Caffe Tensorflow Pytorch Paddlepaddle Keras 深度视觉计算机视觉框架 OpenVINO TensorRT onnxruntime Deepface YOLO/DarkNet mmdetection Paddle-detection/seg/ocr …
最新文章