代码随想录算法训练营第三十四天

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

这道题和第三十三天的题的解法差不多,只不过这次不用判断dp[target]是否等于target了,而是求dp[target]最大是多少。这道题要求剩下石头最小的质量是多少,那么就把他们分成两半,两半的重量足够接近的时候,剩下石头最小的质量就越接近0,因此求出背包容量为sum/2的背包,最多能装多少重量的石头,然后拿这个值减去sum可得到另外一半的重量  两个相减即可得到最终的结果。

class Solution {
public:int lastStoneWeightII(vector<int>& stones) {vector<int> dp(15001, 0);int sum = 0;for (int i = 0; i < stones.size(); i++) sum += stones[i];int target = sum / 2;for (int i = 0; i < stones.size(); i++) { // 遍历物品for (int j = target; j >= stones[i]; j--) { // 遍历背包dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);}}return sum - dp[target] - dp[target];}
};

494. 目标和

在回溯算法系列中,一起学过这道题目回溯算法:39. 组合总和 (opens new window)的录友应该感觉很熟悉,这不就是组合总和问题么?因为只有两个选择 +或者-  因此可以暴力回溯解答出来 但是时间会超时。下面是回溯的代码。

class Solution {
public:vector<int> path;void backtracking(vector<int>& nums, int startIndex, int& result, int target) {if (path.size() == nums.size()) {int sum = accumulate(path.begin(), path.end(), 0);if (sum == target) result++;}for (int i = startIndex; i < nums.size(); i++) {path.push_back(nums[i]);backtracking(nums, i + 1, result, target);path.pop_back();path.push_back(-nums[i]);backtracking(nums, i + 1, result, target);path.pop_back();}}int findTargetSumWays(vector<int>& nums, int target) {int result = 0;backtracking(nums, 0, result, target);return result;}
};

这道题目的数可以分为两个集合 一个全是正数一个全是负数

假设加法的集合总和为x,那么减法对应的总和就是sum - x。

所以我们要求的是 x - (sum - x) = target

x = (target + sum) / 2

此时问题就转化为,装满容量为x的背包,有几种方法,也就是装满正数的集合有几种方法。剩下的就是负数的集合

这里的x,就是bagSize,也就是我们后面要求的背包容量。 并且如果(target + sum) / 2不能整除的话那么说明就无法凑成结果为sum的正负数集合。

再回归到01背包问题,为什么是01背包呢?

因为每个物品(题目中的1)只用一次!

这次和之前遇到的背包问题不一样了,之前都是求容量为j的背包,最多能装多少。

本题则是装满有几种方法。其实这就是一个组合问题了。

1. 确定dp数组以及下标的含义

dp[j] 表示:nums[0]到nums[i]的数据里填满j(包括j)这么大容积的包,有dp[j]种方法

2. 确定递推公式

有哪些来源可以推出dp[j]呢?

只要搞到nums[i],凑成dp[j]就有dp[j - nums[i]] 种方法。

例如:dp[j],j 为5,

  • 已经有一个1(nums[i]) 的话,有 dp[4]种方法 凑成 容量为5的背包。
  • 已经有一个2(nums[i]) 的话,有 dp[3]种方法 凑成 容量为5的背包。
  • 已经有一个3(nums[i]) 的话,有 dp[2]种方法 凑成 容量为5的背包
  • 已经有一个4(nums[i]) 的话,有 dp[1]种方法 凑成 容量为5的背包
  • 已经有一个5 (nums[i])的话,有 dp[0]种方法 凑成 容量为5的背包

那么凑整dp[5]有多少方法呢,也就是把 所有的 dp[j - 0nums[i]] 累加起来。

所以求组合类问题的公式,都是类似这种:

dp[j] += dp[j - nums[i]]

3.  dp数组如何初始化

背包容量0理解成什么都装不下就是0,理解成只有什么都不装就是1,这里要求的是装法,所以dp[0]初始化为1。

4. 遍历顺序

我们讲过对于01背包问题一维dp的遍历,nums放在外循环,target在内循环,且内循环倒序。

从前nums[i]的数据里取数能填满dp[j]的方法数

完整代码如下:

class Solution {
public:int findTargetSumWays(vector<int>& nums, int S) {int sum = 0;for (int i = 0; i < nums.size(); i++) sum += nums[i];if (abs(S) > sum) return 0; // 此时没有方案if ((S + sum) % 2 == 1) return 0; // 此时没有方案int bagSize = (S + sum) / 2;vector<int> dp(bagSize + 1, 0);dp[0] = 1;for (int i = 0; i < nums.size(); i++) {for (int j = bagSize; j >= nums[i]; j--) {dp[j] += dp[j - nums[i]];}}return dp[bagSize];}
};

474. 一和零

这道题的背包的容量有两个维度,不是以前的只有一个维度,因此dp数据应该是二维的了(其实是三维的,如果不是滚动数组的话)这两个维度,一个是m 一个是n,而不同长度的字符串就是不同大小的待装物品。

dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]

dp[i][j] 可以由前一个strs里的字符串推导出来,strs里的字符串有zeroNum个0,oneNum个1。

dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。

所以递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);

zeroNumh和oneNum是当前装入的str的0的个数和1的个数类似于01背包的递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

因为物品价值不会是负数,初始为0,保证递推的时候dp[i][j]不会被初始值覆盖。

01背包为什么一定是外层for循环遍历物品,内层for循环遍历背包容量且从后向前遍历!

那么本题也是,物品就是strs里的字符串,背包容量就是题目描述中的m和n。

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {vector<vector<int>> dp(m + 1, vector<int> (n + 1, 0)); // 默认初始化0for (string str : strs) { // 遍历物品int oneNum = 0, zeroNum = 0;for (char c : str) {if (c == '0') zeroNum++;else oneNum++;}for (int i = m; i >= zeroNum; i--) { // 遍历背包容量且从后向前遍历!for (int j = n; j >= oneNum; j--) {dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);}}}return dp[m][n];}
};

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

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

相关文章

TypeScript体操(一):从基础到进阶

目录 前言Utility Types 是什么&#xff1f;常用 Utility Types前置知识typeofkeyoftypeof 和 keyof 的区别never 关键字extends 关键字结合条件判断infer 类型推断&#xff08;模式匹配&#xff09;判断是与非判断两个类型是否相等或兼容 循环递归嵌套字符串数组协变&#xff…

NMEA2000在船舶控制系统中航空插头插座组件特性

NMEA2000在船舶控制系统中的应用概述 NMEA2000协议是船舶电子设备之间通信的国际标准&#xff0c;广泛应用于船舶导航、监控和自动化系统。它基于CAN&#xff08;Controller Area Network&#xff09;总线技术&#xff0c;以确保在恶劣环境下的可靠性和效率。NMEA2000协议定义了…

英语语法第八课副词

文章目录 1、副词分类1.1 时间副词&#xff0c;表示时间或频率1.2 地点副词&#xff0c;表示地点或位置1.3 方式副词&#xff0c;表示行为方式1.4 程度副词&#xff0c;表示动作程度1.5 疑问副词&#xff0c;引导特殊疑问句1.6 强调副词&#xff0c;强调形容词或动词1.7 连接副…

隐语隐私计算实训营「联邦学习」第 5 课:基于隐私保护的机器学习算法介绍

【隐私计算实训营】是蚂蚁集团隐语开源社区出品的线上课程&#xff0c;自实训营上线以来&#xff0c;获得行业内外广泛关注&#xff0c;吸引上千余名开发者报名参与。本次暑期夏令营课程中&#xff0c;除了最新上线的「联邦学习系列」&#xff0c;还包含了「隐私保护数据分析」…

Java项目实战springboot校园失物招领系统

✌网站介绍&#xff1a;✌10年项目辅导经验、专注于计算机技术领域学生项目实战辅导。 ✌服务范围&#xff1a;Java(SpringBoo/SSM)、Python、PHP、Nodejs、爬虫、数据可视化、小程序、安卓app、大数据等设计与开发。 ✌服务内容&#xff1a;免费功能设计、免费提供开题答辩P…

3D建模软件--犀牛Rhino for Mac

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功 三、运行测试安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件…

初学Mybatis之配置解析

MyBatis 中文网配置教程 mybatis-config.xml 环境配置&#xff08;environments&#xff09; 尽管可以配置多个环境&#xff0c;但每个 SqlSessionFactory 实例只能选择一种环境 可以有多个 enviroment&#xff0c;但是 enviroments default&#xff08;默认&#xff09;只…

玩转springboot之springboot启动原理

启动原理 注意&#xff1a;使用版本为spring-boot-2.2.2.RELEASE springboot启动的入口肯定是main方法啦&#xff0c;那就从main方法入口走起来看看是如何进行启动的 SpringBootApplication public class ConsulApp {public static void main(String[] args) {// 调用SpringAp…

动态规划题目:单词拆分/三角形最小路径和 - leetcode

动态规划思想 / 步骤 &#xff1a; 先将 当前要求 总结成一个 精炼的 小问题 &#xff0c; 然后 将 求解题目 转换为 求解N个 小问题 &#xff0c; 每个小问题的 求解过程相同 &#xff0c;但是 过程涉及 的 数据 是不同的 &#xff0c; 例如第三个 小问…

c++网络编程实战——开发基于ftp协议的文件传输模块(二) 配置ftp服务与手动执行ftp命令

配置FTP服务 一.前言 博主的环境是阿里云服务器&#xff0c;操作系统版本为 ubuntu20.04,一下所有操作都基于以上环境下进行的操作&#xff0c;同时为了简化操作我将开放同一个云服务器的不同端口&#xff0c;让它同时充当服务端和客户端&#xff0c;大家如果想测试效果更好且…

[web]-反序列化-base64

看到源码 <?php error_reporting(0); class A {public $contents "hello ctfer";function __toString(){if ((preg_match(/^[a-z]/i,$this->contents))) {system("echo $this->contents");return 111;}else{return "...";}} }functi…

Zookeeper集群中节点之间数据是如何同步的

1.首先集群启动时&#xff0c;会先进行领导者选举&#xff0c;确定哪个节点是Leader&#xff0c;哪些节点是Follower和Observer 2.然后Leader会和其他节点进行数据同步&#xff0c;采用发送快照和发送Diff日志的方式 3.集群在工作过程中&#xff0c;所有的写请求都会交给Lead…

ImageView实现原理分析

ImageView 是 Android 中用于显示图片的一个基本视图组件。它继承自 View 类&#xff0c;并且可以用来展示静态的图像资源&#xff0c;如位图、动画 GIF、矢量图形等。下面我们将结合源码分析 ImageView 的实现原理。 1. 构造方法与初始化 ImageView 的构造方法和其他 View 子…

WPF串口通讯程序

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using HardwareCommunications; using System.IO.Ports; using System.Windows;namespace PortTest {/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainW…

怀庄之醉是勾兑酒吗?

关于“怀庄之醉是否是勾兑酒”的问题&#xff0c;需要从多个角度进行分析。 勾兑酒在白酒生产中是一个广泛存在的工艺过程&#xff0c;它并非贬义词&#xff0c;而是指将不同口味、不同生产时间、不同度数的纯粮食酒&#xff0c;或固态法白酒与液态法白酒、食用酒精等&#xff…

软件缺陷(Bug)、禅道

目录 软件缺陷的判定标准 软件缺陷的核心内容 构成缺陷的基本要素 缺陷报告 缺陷管理 缺陷的跟踪流程 项目管理工具--禅道 软件在使用过程中存在的任何问题&#xff08;如&#xff1a;错误、异常等&#xff09;&#xff0c;都叫软件的缺陷&#xff0c;简称bug。 软件缺…

如何选择海洋船舶用总线NMEA 2000连接器

NMEA 2000连接器概述 NMEA 2000连接器是现代船舶通信系统中不可或缺的部分&#xff0c;主要用于连接船上各种电子设备&#xff0c;实现数据传输和设备控制。这些连接器遵循NMEA 2000协议标准&#xff0c;支持高速数据传输&#xff0c;并具有良好的防水、耐腐蚀性能&#xff0c…

神经网络之循环神经网络

目录 一、循环神经网络概述&#xff1a;1.传统神经网络与循环神经网络的区别&#xff1a;2.循环神经网络定义&#xff1a; 图片来自&#xff1a;深度学习———循环神经网络 一、循环神经网络概述&#xff1a; 1.传统神经网络与循环神经网络的区别&#xff1a; MLP、卷积神经…

【PostgreSQL教程】PostgreSQL 选择数据库

博主介绍:✌全网粉丝20W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

关于unicloud 云函数开发 加密的问题

解决的问题&#xff1a; 1.在云函数请求过程中入参参数暴露 2.云函数请求结束之后 出参结果暴露 解决方法&#xff1a; 1.在请求过程中对云函数的入参进行加密&#xff0c;在后端接收的时候将加密信息进行解密&#xff0c;根据自己的逻辑成功之后加密返回给前端 前端解密之…