代码随想录算法训练营第四十五天|1049.最后一块石头的重量II、494.目标和、 474.一和零

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

文档讲解:代码随想录

题目链接:. - 力扣(LeetCode)

 本题其实就是尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了

和昨天讲解的416. 分割等和子集 (opens new window)非常像了。

本题物品的重量为stones[i],物品的价值也为stones[i]。

对应着01背包里的物品重量weight[i]物品价值value[i]

背包的容量为所有石块的重量的一半

尽量凑,找到背包中能装下的最大值,

接下来进行动规五步曲:

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

dp[j]表示容量(这里说容量更形象,其实就是重量)为j的背包,最多可以背最大重量为dp[j]

可以回忆一下01背包中,dp[j]的含义,容量为j的背包,最多可以装的价值为 dp[j]。

相对于 01背包,本题中,石头的重量是 stones[i],石头的价值也是 stones[i] ,可以 “最多可以装的价值为 dp[j]” == “最多可以背的重量为dp[j]”

 确定递推公式

01背包的递推公式为:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

本题则是:dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);

一些同学可能看到这dp[j - stones[i]] + stones[i]中 又有- stones[i] 又有+stones[i],看着有点晕乎。

大家可以再去看 dp[j]的含义。

dp数组如何初始化

既然 dp[j]中的j表示容量,那么最大容量(重量)是多少呢,就是所有石头的重量和。

因为提示中给出1 <= stones.length <= 30,1 <= stones[i] <= 1000,所以最大重量就是30 * 1000 。

而我们要求的target其实只是最大重量的一半,所以dp数组开到15000大小就可以了。

当然也可以把石头遍历一遍,计算出石头总重量 然后除2,得到dp数组的大小。

接下来就是如何初始化dp[j]呢,因为重量都不会是负数,所以dp[j]都初始化为0就可以了,这样在递归公式dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);中dp[j]才不会初始值所覆盖。

遍历顺序

倒叙遍历

最后结果推导

最后dp[target]里是容量为target的背包所能背的最大重量。

那么分成两堆石头,一堆石头的总重量是dp[target],另一堆就是sum - dp[target]。

在计算target的时候,target = sum / 2 因为是向下取整,所以sum - dp[target] 一定是大于等于dp[target]的

那么相撞之后剩下的最小石头重量就是 (sum - dp[target]) - dp[target]。

class Solution:def lastStoneWeightII(self, stones: List[int]) -> int:#整个石头的重量可能不是2的倍数?,向下取整total_sum = sum(stones)target = total_sum//2dp = [0] * (target+1)for stone in stones:#注意循环的范围for j in range(target,stone-1,-1):dp[j]  = max(dp[j],dp[j-stone]+stone)##最后的返回值为什么是这样的return total_sum-2*dp[-1]

难点:怎么转化为是01背包问题

补充:

  • %(取模运算符)

    • 功能:计算两个数相除的余数。
    • 例子:7 % 3 的结果是 1,因为 7 除以 3 的余数是 1
  • /(除法运算符)

    • 功能:计算两个数相除的商,结果是浮点数。
    • 例子:7 / 3 的结果是 2.3333333333333335,因为 7 除以 32.333...
  • //(整数除法运算符)

    • 功能:计算两个数相除的商,结果是整数(向下取整)。
    • 例子:7 // 3 的结果是 2,因为 7 除以 32.333...,向下取整得到 2

494.目标和 

文档讲解:代码随想录

题目链接:. - 力扣(LeetCode)

 和之前的组合总和有点像,后面对比一下

放加法的是一个集合(left),减法是一个集合(right)

left组合 - right组合 = target。

left + right = sum,而sum是固定的。right = sum - left

公式来了, left - (sum - left) = target 推导出 left = (target + sum)/2 。(如果不能整除,说明题目中没有满足的组合)

target是固定的,sum是固定的,left就可以求出来。

此时问题就是在集合nums中找出和为left的组合。也就是装满容量为left的容器有多少方法

纯01背包问的是装满这个背包,它的最大价值是多少,分割等和子集问的是能不能装满这个背包,最后一块石头的重量是给我们一个背包,让我们尽量去装,而本题问的是给一个背包的容量,有多少种方法装满,这三道题都是01背包在不同层面上的应用

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

 dp[j]装满容量为j的背包有多少种方法

 确定递推公式

有哪些来源可以推出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 - nums[i]] 累加起来。

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

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

 dp数组如何初始化(不懂)

从递推公式可以看出,在初始化的时候dp[0] 一定要初始化为1,因为dp[0]是在公式中一切递推结果的起源,如果dp[0]是0的话,递推结果将都是0。

这里有录友可能认为从dp数组定义来说 dp[0] 应该是0,也有录友认为dp[0]应该是1。

其实不要硬去解释它的含义,咱就把 dp[0]的情况带入本题看看应该等于多少。

如果数组[0] ,target = 0,那么 bagSize = (target + sum) / 2 = 0。 dp[0]也应该是1, 也就是说给数组里的元素 0 前面无论放加法还是减法,都是 1 种方法。

遍历顺序

01背包倒序遍历

class Solution:def findTargetSumWays(self, nums: List[int], target: int) -> int:total_sum = sum(nums)if (total_sum+target) %2 !=0 :return 0if abs(target)> total_sum:return 0left = (total_sum+target) // 2dp=[0] *(left+1) #装满left背包有多少方法dp[0]=1   #为什么要这样初始化?for num in nums:for j in range(left,num-1,-1):dp[j] += dp[j-num]return dp[left]

474.一和零

 文档讲解:代码随想录

题目链接:​​​​​​​​​​​​​​. - 力扣(LeetCode)

本题中strs 数组里的元素就是物品,每个物品都是一个!

而m 和 n相当于是一个背包,两个维度的背包

m和n就是形容一种容器,装满这个容器最多有多少个元素就输出多少个

理解成多重背包的同学主要是把m和n混淆为物品了,感觉这是不同数量的物品,所以以为是多重背包。

但本题其实是01背包问题!

只不过这个背包有两个维度,一个是m 一个是n,而不同长度的字符串就是不同大小的待装物品。

容器有两个维度,物品也是有两个维度,x个0,和y个1,重量就是[x,y]

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

二维dp数组

dp[m][n] :装满m个0,n个1最多背了多少个物品

 确定递推公式

两个维度,放不放当前物品(x,y)

dp[i][j] = max(dp[i][j], dp[i-x][j-y] + 1)

 dp数组如何初始化

dp[0][0] = 0

非0下标也初始为0

遍历顺序

先遍历物品,再遍历背包,背包倒序遍历

class Solution:def findMaxForm(self, strs: List[str], m: int, n: int) -> int:dp = [[0 for _ in range(n+1)] for _ in range(m+1)]#遍历物品for str in strs:x = 0y = 0for char in str:if char == '0':x+=1else:y += 1#遍历背包for i in range(m,x-1,-1): #存放0的个数,如果写为0,结果会不对for j in range(n,y-1,-1):#存放1的个数dp[i][j] = max(dp[i][j],dp[i-x][j-y]+1)return dp[m][n]

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

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

相关文章

visual studio code 全局搜索

VScode写代码的时候&#xff0c;会经常性的需要进行查找代码&#xff0c;那么怎么在Visual Studio Code中进行查找呢&#xff0c;下面就来大家vscode全局搜索的方法。 想要在vscode全局搜索进行全局搜索&#xff0c;使用快捷键CTRLSHIFTF即可进行搜索&#xff0c;也可以在左边…

哪吒监控+cfcdn+ 反代grp端口

哪吒监控cfcdn 反代grp端口 背景&#xff1a; 哪吒监控&#xff1a;感觉VPS线路不稳定&#xff0c;为了打消自己潜意识&#xff0c;希望量化延迟。 cfcdn&#xff1a;隐藏真实站点&#xff0c;保障小鸡隐秘安全 反代grpc端口: 反代grpc到支持https(TLS)的端口&#xff0c;这…

Tomcat启动闪退问题及解决方法

Tomcat启动闪退问题可能由多种原因引起&#xff0c;以下是一些常见的原因及相应的解决方法&#xff0c;按照清晰的结构进行归纳&#xff1a; 一、环境变量问题 Java环境问题&#xff1a;Tomcat依赖于Java环境&#xff0c;如果JDK未正确安装或环境变量配置不正确&#xff0c;会…

Elasticsearch 认证模拟题 - 3

1、题目 有一索引有 3 个字段&#xff0c;请写一个查询去匹配这三个字段&#xff0c;并且将三个字段的评分相加作为最后的总评分 # 创建索引 PUT task {"mappings": {"properties": {"fielda":{"type": "text"},"fie…

TrueNAS开启SSH登录ROOT

简介: 从 SCALE Bluefin 22.12.0 开始,为了加强安全性并遵守联邦信息处理标准 (FIPS),root帐户登录已被弃用。所有 TrueNAS 用户都应创建具有所有必需权限的本地管理员帐户,并开始使用它来访问 TrueNAS。当根用户密码被禁用时,只有管理用户帐户才能登录 TrueNAS Web 界面。…

从零学算法2965

2965. 找出缺失和重复的数字 给你一个下标从 0 开始的二维整数矩阵 grid&#xff0c;大小为 n * n &#xff0c;其中的值在 [1, n2] 范围内。除了 a 出现 两次&#xff0c;b 缺失 之外&#xff0c;每个整数都 恰好出现一次 。 任务是找出重复的数字a 和缺失的数字 b 。 返回一个…

轮状病毒简介-卡梅德生物

轮状病毒是一种非常常见的病毒&#xff0c;主要影响婴幼儿和小孩&#xff0c;引起严重的胃肠炎&#xff0c;表现为严重腹泻、呕吐、发烧和脱水。这种病毒全球流行&#xff0c;是全世界五岁以下儿童因腹泻导致死亡的主要原因之一。轮状病毒属于Reoviridae家族&#xff0c;具有双…

逻辑回归【python,机器学习,算法】

逻辑回归是一种有监督的学习分类算法&#xff0c;用于预测目标变量的概率。目标或因变量的性质是二分法的&#xff0c;这意味着将只有两个可能的类。主要解决二分类问题。 主要步骤有三个&#xff1a; 求线性回归曲线。通过 sigmoid 函数将线性回归曲线转为 0-1 范围函数。 …

机器学习-11-使用kaggle命令下载数据集和操作指南

参考kaggle API 命令下载数据集 参考Kaggle操作完整指南(2023版) 参考Kaggle如何入门? 1 kaggle操作指南 Kaggle 是一个流行的数据科学竞赛平台。由 Goldbloom 和 Ben Hamner 创建于 2010 年。为什么这两个家伙要创立这样一个平台呢? 数据科学社区一直有这样一个难题:对…

低代码开发平台(Low-code Development Platform)的模块组成部分

低代码开发平台&#xff08;Low-code Development Platform&#xff09;的模块组成部分主要包括以下几个方面&#xff1a; 低代码开发平台的模块组成部分可以按照包含系统、模块、菜单组织操作行为等维度进行详细阐述。以下是从这些方面对平台模块组成部分的说明&#xff1a; …

docker安装mysql8和mysql5.7

1.docker安装mysql5.7,请点击此链接 2.docker安装mysql8并挂载数据卷 docker pull mysql:8.0 docker run --name mysql8 -e MYSQL_ROOT_PASSWORDmy-secret-pw -d mysql:8.0 docker run --name mysql8 -e MYSQL_ROOT_PASSWORD123456 -v /mqq/mysql8/datadir:/var/lib/mysql -d…

虚拟dom的理解

由普通的js对象来描述dom对象&#xff0c;是对于真实dom的映射&#xff0c;因为不是真实的dom对象所以叫虚拟dom。因为js处理数据的速度比操作dom的速度更快&#xff0c;性能更好&#xff0c;所以让现代这些react vue 等框架都采用了虚拟dom。 key值是唯一性的,在虚拟dom树进行…

【喜报】科大睿智服务企业通过CMMI3级认证

​北京建投科信科技发展股份有限公司&#xff08;以下简称“北京建投科技” &#xff09;前身为北京银帝科技发展公司&#xff0c;成立于1993年&#xff0c;注册资本6,000万元&#xff0c;为中国建银投资有限责任公司&#xff08;简称“中国建投”&#xff09;的成员企业建投华…

现在,所有人都能免费用GPT-4o了!

OpenAI今日官宣&#xff0c;ChatGPT正式向所有用户免费开放&#xff01;所有用户均可以访问定制化GPT、分析图表、询问有关照片的问题以及5月初GPT-4o添加的其他功能。 OpenAI今天在X上发布推文&#xff1a; 「所有ChatGPT免费用户现在都可以使用浏览、视觉、数据分析、文件上…

element table表格行列合并span-method,根据数据动态行列合并

表格行列合并需要用到 table的方法 span-method 根据数据来进行动态的行列合并&#xff0c;实例如下&#xff1a; <el-table:data"tableData":span-method"objectSpanMethod" style"width: 100%"><el-table-columnprop"key"l…

mac电脑生成文件下载URL

1.首先打开web共享&#xff0c;终端方式。 开始 sudo apachectl start 停止&#xff1a; sudo apachectl stop 重启&#xff1a; sudo apachectl restart 2.将需要下载的文件 app.v1.6.12_note.apk /Library/WebServer/Documents/ 目录下 3. 同一网络下&#xff0c;直接用…

C++系列——————类和对象(上)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、面向对象的三大特征二、类的引入2.1类的定义 三.类的访问限定符3.1访问限定符的介绍3.2.访问限定符的使用 四、类的作用域五、类的实例化六、类对象模型6.1…

JavaScript的内存管理机制

No.内容链接1Openlayers 【入门教程】 - 【源代码示例300】 2Leaflet 【入门教程】 - 【源代码图文示例 150】 3Cesium 【入门教程】 - 【源代码图文示例200】 4MapboxGL【入门教程】 - 【源代码图文示例150】 5前端就业宝典 【面试题详细答案 1000】 文章目录 一、内存…

Pipecat: 创建语音对话agent的开源框架,支持多模态!

项目简介 pipecat 是用于构建语音&#xff08;和多模态&#xff09;对话代理的框架。诸如私人教练、会议助理、儿童讲故事玩具、客户支持机器人、摄入流程和尖刻的社交伙伴。 看看一些示例应用&#xff1a; 语音代理入门 您可以开始在本地计算机上运行 Pipecat&#xff0c;然…

Nginx(openresty) 开启目录浏览 以及进行美化配置

1 nginx 安装 可以参考:Nginx(openresty) 通过lua结合Web前端 实现图片&#xff0c;文件&#xff0c;视频等静态资源 访问权限验证&#xff0c;进行鉴权 &#xff0c;提高安全性-CSDN博客 2 开启目录浏览 location /file{alias /data/www/; #指定目录所在路径autoindex on; …