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

常学常新:《Attention Is All You Need》万字解读! 阅读详情

最后一块石头的重量II

1049. 最后一块石头的重量 II - 力扣(LeetCode)

考虑昨天的能否将一个数组分为两个和相等的子集,本题有类似的思路,即将左右分为左右两个和相近的子集,然后返回其差值,这里使用动态规划的话。

DP数组含义,dp[j]表示能够达到的总重量为j的石头的最大重量

背包容量从0到1501(根据题目要求变化)

dp[j] = max(dp[j], dp[j-nums[i]] + nums[i]),j为重量,i为石头的选择与否。

遍历顺序同样物品遍历在外,背包遍历在内层,且内层倒序遍历。

最后考虑对最后一块石头重量的返回。考虑到dp[j]为其中一个子集所能抵达的最大重量,则另外一个子集的重量为总重量减去子集1的重量,要得到最后一块石头的重量,为两个子集和的相减值,最后的结果可以表示为sum -= 2*dp[j]。

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        // 创建一个长度为1501,全0的数组dp,用于动态规划
        // dp[j]表示能够达到的总重量为j的石头的最大重量
        vector<int> dp(1501, 0);
        int sum = 0;
        // 计算stones数组中所有石头的总重量
        for (auto x : stones) {
            sum += x;
        }
        // 计算目标和,即分割后两堆石头的总重量应该接近sum/2
        const int target = sum / 2;
        for (int i = 0; i < stones.size(); i++) {
            // 从大到小遍历目标和及其以下的值
            for (int j = target; j >= stones[i]; j--) {
                // 更新dp[j],选取当前石头和不选取当前石头,取两种情况的最大值
                dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
            }
        }
        // 最终结果为sum - dp[target]的两倍,因为dp[target]是接近sum/2的最大重量
        // 所以sum - dp[target]是另一堆石头的重量,两堆石头碰撞后剩下的最小重量就是它们的差
        return sum - 2 * dp[target];
    }
};

算法的时间复杂度为O(n^2),空间复杂度为O(n)。

目标和

494. 目标和 - 力扣(LeetCode)

动态规划之背包问题,装满背包有多少种方法?| LeetCode:494.目标和_哔哩哔哩_bilibili

得到目标和,需要在数字前面添加加号和减号,即存在两个数组我们假定为left数组和right数组,left数组中元素前全为加号,right数组中元素前全为减号。目标和为target,元素的所有和为sum。

sum_left + sum_right = target;

sum_left - sum_right = sum;

sum_left = (target + sum)/2,即我们能够得到left数组的和为target和元素和sum的一半。

使用动态规划算法来解决这个问题。

此时的dp[j]表示的是要装满容量为j的背包共有dp[j]种方式。

dp[j]:装满容量为j的背包有dp[j]种方式。

dp[j]的推导公式,这里需要牢记 dp[j]表示的是装满容量为j的背包的所有方式数量,所以dp[j]与dp[j-nums[j]]相关。即总容量为5,我们有一个质量为1的物品,则应该有dp[4]种方法能够得到5(1+4 = 5),若我们有一个质量为2的物品,应该有dp[3]种方法能够得到5(2+3 = 5 考虑之前的爬楼梯的题目),依次向下推,则dp[5] = dp[4] + dp[3] + dp[2] + dp[1] + dp[0]。

dp[j] += dp[j-nums[i]],此处为累加

dp[0]本应为0,但这里若初始为0,则所有dp均为0,所以初始化为1,非0下标初始化为0。

遍历顺序物品遍历在外,背包遍历在内层,且内层倒序遍历。

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        int sum = 0;
        // 计算数组nums中所有数字的和
        for (auto x : nums) {
            sum += x;
        }
        // 如果(target + sum)是奇数,那么不可能通过添加+或-得到target,因为每添加一个-,总和就会减少两倍
        if ((target + sum) % 2 == 1) {
            return 0;
        }
        // 如果target的绝对值大于sum,那么也不可能得到target,leetcode有反例[100] target -200
        if (abs(target) > sum) {
            return 0;
        }
        // 计算我们需要的正数总和left
        const int left = (sum + target) / 2;
        // 初始化动态规划数组dp,大小为left+1,初值都为0,dp[j]表示总和为j的方法数
        vector<int> dp(left + 1, 0);
        // 总和为0的方法只有1种,即不选择任何数字
        dp[0] = 1;
        // 遍历数组nums中的每个数字
        for (int i = 0; i < nums.size(); i++) {
            // 从大到小遍历left及其以下的值
            for (int j = left; j >= nums[i]; j--) {
                // 更新dp[j],考虑选择当前数字和不选择当前数字的情况
                dp[j] += dp[j - nums[i]];
            }
        }
        // 返回总和为left的方法数,即dp[left]
        return dp[left];
    }
};

算法的时间复杂度为O(n^2),空间复杂度为O(n)。

一和零

474. 一和零 - 力扣(LeetCode)

本题还是一个01背包问题,虽然有两个维度。具体参考如下网站

代码随想录 (programmercarl.com)

动态规划之背包问题,装满这个背包最多用多少个物品?| LeetCode:474.一和零_哔哩哔哩_bilibili

我们需要装满m个0,n个1的背包,共2个维度,需要一个二维的dp数组,背包中最多有多少个物品,dp[i][j]即表示最多背的物品个数,即最后返回值为dp[m][n]。

dp[i][j] = max(dp[i][j-1],dp[i][j]) x和y分别表示物品i中有x个0,y个1,此处max中的dp[i][j]参考之前背包问题的滚动数组,做了压缩。

对dp数组进行初始化,dp[0][0] = 0,其余值也全赋值为0。同样参考之前背包问题的滚动数组,dp[i][j]的值在每次遍历过程中会被覆盖。

遍历顺序,先遍历物品,再遍历背包,且背包要倒序遍历。

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        // 初始化动态规划数组dp,大小为(m+1) x (n+1),初值都为0
        // dp[i][j]表示最多能组成多少个只包含0和1的字符串,且0的数量不超过i,1的数量不超过j
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));

        // 遍历数组strs中的每个字符串
        for (string str : strs) {
            int zero_count = 0; // 记录当前字符串中0的数量
            int one_count = 0;  // 记录当前字符串中1的数量
            // 遍历当前字符串中的每个字符
            for (auto c : str) {
                if (c == '0') {
                    zero_count++;
                } else {
                    one_count++;
                }
            }
            // 从大到小遍历m和n,更新dp数组
            for (int i = m; i >= zero_count; i--) {
                for (int j = n; j >= one_count; j--) {
                    // 更新dp[i][j],考虑选择当前字符串和不选择当前字符串的情况
                    dp[i][j] = max(dp[i - zero_count][j - one_count] + 1, dp[i][j]);
                }
            }
        }
        // 返回最多能组成只包含0和1的字符串的数量,即dp[m][n]
        return dp[m][n];
    }
};

算法的时间复杂度为O(m*n*k),k为strs的长度,外层遍历str数组中的每个字符串,共有strs.size()次迭代,k为strs数组的总长度,为strs.size()*每个数组中元素的平均长度L。

空间复杂度考虑需要维护一个二维dp数组,为O(m*n)。

Win11网络卡顿?用Wireshark抓包5分钟定位问题(保姆级实战) 本文详细介绍了如何使用Wireshark在Win11系统中快速定位网络卡顿问题。通过5分钟抓包分析,作者成功发现TCP重传率高达37%的罪魁祸首,并提供了从准备工作到实战分析的保姆级教程,帮助用户解决游戏卡顿、视频会议延迟等常见网络问题。 阅读详情

相关推荐

SAP 资产主数据屏幕增强:对比字段追加与子屏幕/页签 2 种方案优劣

本文深入对比了SAP资产主数据(AS01/AS03)屏幕增强的两种方案:字段追加与子屏幕/页签。从技术实现、业务适配、系统维护等维度分析各自优劣,提供方案选型决策树和混合方案实践建议,帮助企业在SAP实施中做出最优选择。

weixin_28559803的博客 283

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

题目链接:LeetCode 1049. 最后一块石头的重量 II思路: sum - 2*dp[target]; 注意 :题目链接:LeetCode 494. 目标和 思路: 组合问题,就是将所有没放nums[i]的情况 加上现有情况,遍历。 注意 :题目链接:LeetCode 474.一和零 思路: 注意 : 1. 2. 3. 4.题目链接:LeetCode 704 二分查找思路:二维01背包 注意 :

qq_24817679的博客 509

从5V降到3.3V,你的LDO到底有多烫?手把手算功耗、选散热,避开这些坑

本文详细解析了LDO在5V转3.3V电路中的发热问题,提供了精确的功耗计算公式和散热设计方法。通过对比不同封装的热阻参数和优化PCB布局,帮助工程师有效降低LDO温度,避免热保护触发。文章还探讨了替代方案的技术拐点,为电源系统优化设计提供实用指导。

weixin_30304375的博客 433

代码随想录算法训练营Day42 | 1049. 最后一块石头的重量 II、494. 目标和、474.一和零 | Python | 个人记录向

动态规划:1049. 最后一块石头的重量 II、494. 目标和、474.一和零。

Python基本算法 402

MIPI DPHY接口(基于Xilinx FPGA实现)案例分析

在Xilinx FPGA实现MIPI DPHY接口的案例(包括CIS协议层)。截止目前为止,Xilinx仅在Ultrascale+及其以上版本的FPGA IO可直接支持MIPI 电平输入,其他的,都需要转换成LVDS来接收。

ONEFPGA的博客 5624

爬取二手房数据:Python爬虫+Geopy实战,看透房价与地理位置的隐藏关系

哪些区域单价虚高(房源少但单价远高于周边);哪些小区性价比高(靠近地铁/学校,单价低于同地段平均水平);房价与地理位置的量化关系(如距离地铁每远1公里,单价下降多少)。如果想扩展分析范围,可爬取多个城市/区域的数据,对比不同城市的房价差异;或结合时间维度(定期爬取),分析房价的涨跌趋势。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 948

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

力扣题目链接(opens new window)题目难度:中等有一堆石头,每块石头的重量都是正整数。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:如果 x == y,那么两块石头都会被完全粉碎;如果 x!= y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。输入:[2,7,4,1,8,1]输出:1。

m0_66462858的博客 170

[QMT量化交易小白入门]-七十六、从tick数据中获取高频交易的量价背离信号

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 790

代码随想录算法训练营Day42 | LeetCode1049. 最后一块石头的重量 II、LeetCode494. 目标和、LeetCode474.一和零

这道题难点在于如何转换成背包问题,其实和上一题和相等子集合基本一样,尽量把石头分成两个重量相等的集合,那么在碰撞之后和就是最小的,石头的重量也可以当作石头的价值,代码也基本一样,就是最后的返回值是返回最小的差值,除法是向下取整,所以sum-dp[target]>dp[target]。代码如下:时间复杂度O(m*n);空间复杂度O(m)。

ckw_lztxdy的博客 564

把静态前端托管进 SAP BTP:HTML5 Application Deployer 与企业级内容部署全攻略

本文介绍了在SAP BTP Cloud Foundry环境中使用HTML5 Application Repository托管前端静态资源的工程化实践。通过HTML5 Application Deployer工具,结合MTA描述、路由配置和服务实例,实现前后端解耦和标准化部署。文章详细阐述了目录结构、关键配置文件、MTA编排以及构建部署流程,并针对大体积前端资源提供了GACD和异步上传两种解决方案。最后说明了如何与AppRouter协同工作,使部署内容可供终端用户访问。这套方法使前端更新无需重启后端,支持团队

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 154

菜鸟哥玩蓝牙Ble4.0系列 ESP32初玩篇③ Beacon —— 广播应用,室内定位,内容推送

文章目录1、前言1.1 什么叫做Beacon?1.2 Beacon使用场景1.3 Beacon协议落地实现2、ESP32 Beacon案例3、Beacon核心库 —— BLEBeacon、BLEEddystoneTLM、BLEEddystoneURL3.1 BLEBeacon3.2 BLEEddystoneTLM3.3 BLEEddystoneURL 授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。

单片机菜鸟哥的博客 2万+

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

力扣题目链接状态:查看思路后AC。将石头重量分成两堆,这两堆的重量要尽可能相近。计算其中一堆的最大重量,因为sum/2向下取整,所以dp[target]肯定是重量较轻的那一堆,最后的答案就是重量较大的那一堆减去dp得到的这一堆,也就是(sum-dp[target]) - dp[target]。++i){--j){

weixin_42179093的博客 221

要理解成本中心与利润中心的根本区别与适用场景,需从 “责任范围、考核核心、管理目标” 三个核心维度切入,同时明确二者在企业管理体系中的联动关系

摘要: 成本中心与利润核心区别在于责任范围、考核目标和管理权限。成本中心仅对成本负责(如生产、行政部门),考核成本控制能力;利润中心需同时管控成本与收入(如独立产品线、区域分公司),以利润为核心指标。选择标准取决于单元是否拥有收入决策权:无收入权的支持/执行部门设为成本中心,能独立经营、核算盈亏的单元设为利润中心。二者协同运作,成本中心为利润中心提供基础支持,利润中心的需求动态影响成本中心资源配置,共同实现企业整体目标。划分本质是确保考核指标与责任范围匹配,避免管理失效。

金牌架构师 656

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

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

Greeneril_的博客 373

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

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

训练营第41天:1049.最后一块石头的重量II、494.目标和、474.一和零

jiabao0520的博客 1557

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Studying-代码随想录训练营day36| 1049.最后一块石头的重量II、494.目标和、474.一和零

1049.最后一块石头的重量II、494.目标和、474.一和零

yachihaoteng的博客 2059

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

代码随想录算法训练营Day31 | Leetcode1049. 最后一块石头的重量 II、494. 目标和、474.一和零

有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。如果 x == y,那么两块石头都会被完全粉碎;如果 x!= y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。

叽里呱啦大王的博客 1182

【代码随想录训练营第42期 Day36打卡 - 动态规划Part4 - LeetCode 1049. 最后一块石头的重量 II 494. 目标和 474.一和零

动态规划--01背包的使用

记得要努力变强 1482

代码随想录算法训练营Day31| LeetCode 1049 最后一块石头的重量 II、494 目标和、474 一和零

代码随想录算法训练营第三十一天内容,0-1背包思想的一些实践,再接再厉!

修炼途中的所见所闻,所思所想。 1149

代码随想录算法训练营三刷day43 | 动态规划之1049. 最后一块石头的重量 II 494. 目标和 474.一和零

题目链接本题其实就是尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。本题物品的重量为stones[i],物品的价值也为stones[i]。对应着01背包里的物品重量weight[i]和 物品价值value[i]。

baimaozi_007的博客 995

代码随想录训练营Day41 | 1049. 最后一块石头的重量 II | 494. 目标和 | 474.一和零

先用 二维 dp数组求解本题,dp[i][j]:使用 下标为[0, i]的nums[i]能够凑满j(包括j)这么大容量的包,有dp[i][j]种方法。所以递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);递推公式:dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]];以输入:["10","0001","111001","1","0"],m = 3,n = 3为例。

m0_68965961的博客 812

算法训练营day36 动态规划④ 1049. 最后一块石头的重量 II、494. 目标和、474.一和零

算法训练营DAY36 递归规律的理解,二维一维区别的理解,以及对于dp数组的理解

m0_65111950的博客 838

代码随想录算法训练营day43|第九章 动态规划part05:1049. 最后一块石头的重量 II、494. 目标和、474.一和零

还有一点,初始化dp数组的时候,必须将dp[0]设置为1,虽然总和为0的方法数不一定是1(例如集合[0, 0 ,0]),即使初始化为1,最后也可能会增加,但如果初始化为0,dp数组就永远都是0(因为遍历背包是倒序遍历,而且除0外所有都初始化为0,所以如果该容量存在方法数,那么一定是从dp[0]开始加起来的,dp[0]=0,那加来加去都只能是0)。这道题需要间接考虑,可以转化为能不能将整个数组尽量分成两个和一样的分数组,这样求最后的石头的质量就是求两个分数组的和之间的最小差值,就变成了和。

mrmobi的博客 1024

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

题目链接文章链接本题使用回溯和动规两种方法进行实现,动规的实现依然难在如何转化为背包问题。本题中strs 数组里的元素就是物品,每个物品都是一个!而m 和 n相当于是一个背包,两个维度的背包。本题的01背包有两个维度,一个是m 一个是n,而不同长度的字符串就是不同大小的待装物品。纯 0 - 1 背包 (opens new window)是求 给定背包容量 装满背包 的最大价值是多少。416. 分割等和子集 (opens new window)是求 给定背包容量,能不能装满这个背包。

m0_68682181的博客 1090

代码随想录算法训练营DAY43|C++动态规划Part5|1049.最后一块石头的重量II、494.目标和、474.一和零

力扣题目链接1049.最后一块石头的重量II这个背包最多能装多少?LeetCode:1049.最后一块石头的重量II状态:想破脑袋想不出来怎么抽象成背包问题看完思路之后的状态:也不用想破脑袋把这些石头尽可能得分成两堆,如果这两堆石头重量相似的话,相撞之后所剩的值就是最小值。

糖炒栗子 1282

代码随想录算法训练营day36

今天是算法营的第36天,希望自己能够坚持下来!今日任务:● 1049. 最后一块石头的重量 II● 494. 目标和● 474.一和零题目链接文章讲解视频讲解不同类型的背包问题,分割等和子集:求是否刚好装满背包,dp[j] = max(dp[j], dp[j - weight[i]] + value[i]) 求dp[target] == target最后一块石头的重量 II:尽可能装满背包,

qq_38365428的博客 1069
上一篇: 代码随想录算法训练营Day41|背包问题、分割等和子集
下一篇: 代码随想录算法训练营Day43|完全背包、518.零钱兑换II、377.组合总和IV、70.爬楼梯(进阶)
viaNoir
博客等级 码龄10年 535粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值