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

题目链接:1049. 最后一块石头的重量 II

思路

        把石头分成重量尽量相同的两堆,这样就能保证最后一块石头的重量最小。转换为01背包问题,重量和价值都是stone。

        ①dp数组,dp[j]表示容量为j的背包可以装的最大价值为dp[j]

        ②递推公式,dp[j] = max(dp[j], dp[j - stone[i]] + stone[i])

        ③dp数组初始化,遍历stone数组,计算总重量,取一半为dp数组大小,值为0;或者根据题目可知最大重量为30*100=30000,取一半15000即可,值为0

        ④遍历顺序,一维dp数组,先物品,后背包,背包倒序遍历

        ⑤推导dp数组

代码

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        if (stones.size() == 1)
            return stones[0];
        int sum = 0;
        // 计算总重量
        for (int a : stones)
            sum += a;
        int target = sum / 2;
        vector<int> dp(target + 1, 0);
        // 先物品
        for (int i = 0; i < stones.size(); i++) {
            // 后背包
            for (int j = target; j >= stones[i]; j--) {
                // 01背包
                dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
            }
        }
        // 分成两堆,一堆dp[target],另一堆sum-dp[target]
        return sum - dp[target] - dp[target];
    }
};

题目链接:494. 目标和

思路

        数组中有若干数字,在每个数字前面放加号或者减号使得最后的结果为target,可以理解为组合问题,使用回溯算法。每次遇到数字都是两种选择,如果最后等于目标,方法种类做累加操作。这种方法的问题在于时间复杂度,每次都是两种选择,并且数组中有若干数字,时间复杂度呈指数增长。

        既然有加减两种运算符,那就将数组分为两个子集,加法子集left,减法子集right,数组所有数字之和为sum,则sum = left + right,target = left - right,联立两式可得left = (sum+target)/2,如此只需要在数组中寻找若干数字,使其和等于left即可,剩下的就是减法子集。将问题转化成了01背包问题。

        ①dp数组,dp[j]表示装满容量为j的背包有dp[j]种方法

        ②递推公式,dp[j] += dp[j-nums[i]],举例,left=5时,装满需要dp[5],而dp[5]可以由dp[4]+dp[1]得到,以此类推

        ③dp数组初始化,dp[0] = 1,因为要进行累加操作,所以dp[0]取1

        ④遍历顺序,先物品,后背包,背包倒序遍历

        ⑤推导dp数组

代码

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        int sum = 0;
        for (int i = 0; i < nums.size(); i++) {
            sum += nums[i];
        }
        // 目标值的绝对值比数组中所有数字和还要大,肯定无解
        if (abs(target) > sum)
            return 0;
        // 不能整除,说明如何构造都满足不了题目要求
        if ((sum + target) % 2 == 1)
            return 0;
        int left = (sum + target) / 2; // 背包容量
        vector<int> dp(left + 1, 0);
        dp[0] = 1; // dp数组初始化
        // 先物品
        for (int i = 0; i < nums.size(); i++) {
            // 后背包,倒序遍历
            for (int j = left; j >= nums[i]; j--) {
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[left];
    }
};

题目链接:474.一和零

思路

        01背包的思路,数组中由若干物品,重量有两个维度,0的个数,1的个数;背包的容量也有两个维度,0和1的容量,m和n,最后求的是背包最多可以装多少件物品。

        重量及容量涉及两个维度,加上所求的物品数量,总共三个变量,所以使用二维dp数组。

        ①dp数组,dp[i][j]表示容量为i个0和j个0的背包最多可以装dp[i][j]件物品

        ②递推公式,dp[i][j] = max(dp[i][j], dp[i-x][j-y] + 1),x表示当前物品0的个数,y表示当前物品1的个数

        ③dp数组初始化,dp[0][0]=0,容量都为0,装不了物品;dp数组中非0容量也初始化为0,这是因为在递推公式中涉及到max取最大值

        ④遍历顺序,先物品,后背包,背包倒序遍历

        ⑤推导dp数组

代码

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0)); // dp数组及初始化
        // 01背包
        // 先物品
        for (string str : strs) {
            int x = 0; // 记录当前物品0的数量
            int y = 0; // 记录当前物品1的数量
            for (char a : str) {
                if (a == '0')
                    x++;
                else
                    y++;
            }
            // 后背包,这里有两个维度0和1,倒序遍历
            for (int i = m; i >= x; i--) {
                for (int j = n; j >= y; j--) {
                    dp[i][j] = max(dp[i - x][j - y] + 1, dp[i][j]);
                }
            }
        }
        return dp[m][n];
    }
};

总结

        ①01背包的基础知识已经理解了,但是如何将题目转换为01背包问题还需要熟练

        ②目前来说,将题目转换为01背包问题,主要是要找到背包与物品,然后确定每种物品只有一件

        ③01背包问题:装满背包的组合有多少种,最多能装多少件物品等

        ④dp数组含义以及递推公式的细节处理

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

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

相关文章

线上线下包搭建小程序/公众号/H5 支持二开!

网上交友有以下三个积极影响&#xff1a; 1. 扩展社交圈和增加社交机会&#xff1a;网上交友可以让人们接触到不同地区、不同背景、不同文化的人&#xff0c;拓展人们的社交圈并且增加交友机会。这些新的社交联系对于个人的成长和发展有积极的影响&#xff0c;可以让人们学习新…

奶爸预备 |《P.E.T.父母效能训练:让亲子沟通如此高效而简单:21世纪版》 / 托马斯·戈登——读书笔记

目录 引出致中国读者译序前言第1章 父母总是被指责&#xff0c;而非受训练第2章 父母是人&#xff0c;不是神第3章 如何听&#xff0c;孩子才会说&#xff1a;接纳性语言第4章 让积极倾听发挥作用第5章 如何倾听不会说话的婴幼儿第6章 如何听&#xff0c;孩子才肯听第8章 通过改…

[每日AI·0506]巴菲特谈 AI,李飞飞创业,苹果或将推出 AI 功能,ChatGPT 版搜索引擎

AI 资讯 苹果或将推出 AI 功能&#xff0c;随 iPhone 发布2024 年巴菲特股东大会&#xff0c;巴菲特将 AI 类比为核技术 巴菲特股东大会 5 万字实录消息称 OpenAI 将于 5 月 9 日发布 ChatGPT 版搜索引擎路透社消息&#xff0c;斯坦福大学 AI 领军人物李飞飞打造“空间智能”创…

leetCode75. 颜色分类

leetCode75. 颜色分类 题目思路 代码 class Solution { public:void sortColors(vector<int>& nums) {for(int i 0, j 0, k nums.size() - 1; i < k;){if(nums[i] 0) swap(nums[i],nums[j]);else if(nums[i] 2) swap(nums[i],nums[k--]);else if(nums[i] …

基于Springboot+Vue+Java的学生就业管理系统

&#x1f49e; 文末获取源码联系 &#x1f649; &#x1f447;&#x1f3fb; 精选专栏推荐收藏订阅 &#x1f447;&#x1f3fb; &#x1f380;《Java 精选实战项目-计算机毕业设计题目推荐-期末大作业》&#x1f618; 更多实战项目~ https://www.yuque.com/liuyixin-rotwn/ei3…

Docker容器:Docker-Consul 的容器服务更新与发现

目录 前言 一、什么是服务注册与发现 二、 Docker-Consul 概述 1、Consul 概念 2、Consul 提供的一些关键特性 3、Consul 的优缺点 4、传统模式与自动发现注册模式的区别 4.1 传统模式 4.2 自动发现注册模式 5、Consul 核心组件 5.1 Consul-Template组件 5.2 Consu…

自动驾驶融合定位:IMU内参模型及标定

自动驾驶融合定位&#xff1a;IMU内参模型及标定 一、 概述 标定的本质是参数辨识。首先明确哪些参数可辨识&#xff0c;其次弄清怎样辨识。 参数包括陀螺仪和加速度计各自的零偏、标度因数、安装误差。 辨识就比较丰富了&#xff0c;如果让各位先不局限于标定任务&#xf…

HCIP-Datacom-ARST必选题库_BGP【道题】

1.关于summary automatic命令和BGP聚合的描述,错误的是? 该命令用于实现自动聚合,其优先级高于手动聚合 配置该命令后,BGP将按自然网段聚合路由 该命令用来使能对本地引入的路由进行自动聚合 配置该命令后,BGP只向对等体发送聚合后的路由 1.关于summary automatic命令和BGP聚…

C++初阶学习第五弹——类与对象(下)——类与对象的收官战

类与对象&#xff08;上&#xff09;&#xff1a;C初阶学习第三弹——类与对象&#xff08;上&#xff09;——初始类与对象-CSDN博客 类与对象&#xff08;中&#xff09;&#xff1a;C初阶学习第四弹——类与对象&#xff08;中&#xff09;——刨析类与对象的核心点-CSDN博…

Linux环境下的事件驱动力量:探索Libevent的高性能I/O架构

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之《Linux环境下的事件驱动力量&#xff1a;探索Libevent的高性能I/O架构》&#xff0c;在这篇文章中&#xff0c;你将会学习到Libevent的高性能I/O原理以及应用&#xff0c;并且我会给出源码…

云仓酒庄携手央视共筑品牌新高度,酒类行业广告战略迈向新征程

随着酒类市场的日益繁荣与竞争的加剧&#xff0c;品牌宣传与推广在酒类行业中的地位愈发凸显。近日&#xff0c;云仓酒庄宣布与中视中州&#xff08;央视代理机构&#xff09;达成2024-2025年度央视广告战略合作&#xff0c;云仓酒庄副总裁周玄代表云仓酒庄签约&#xff0c;这一…

Ubuntu系统安装nvfortran详细步骤【笔记】

实践设备&#xff1a;华硕FX-PRO&#xff08;NVIDIA GeForce GTX 960M&#xff09; Ubuntu系统安装NVFORTRAN&#xff08;NVIDIA Fortran Compiler&#xff09;步骤如下&#xff1a; 安装依赖项&#xff1a;在安装NVFORTRAN之前&#xff0c;你需要确保系统已经安装了一些必要…

Linux学习(一)-- 简单的认识

目录 1. Linux的诞生 2.Linux发行版 拓展&#xff1a; &#xff08;1&#xff09;什么是Linux系统的内核&#xff1f; &#xff08;2&#xff09;什么是Linux系统发行版&#xff1f; 1. Linux的诞生 Linux创始人: 林纳斯 托瓦兹 Linux 诞生于1991年&#xff0c;作者上大学…

Java特性之设计模式【享元模式】

一、享元模式 概述 享元模式&#xff08;Flyweight Pattern&#xff09;主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能。这种类型的设计模式属于结构型模式&#xff0c;它提供了减少对象数量从而改善应用所需的对象结构的方式 享元模式尝试重用现有的同类对…

LeetCode 226.翻转二叉树(全网最多的解法)

LeetCode 226.翻转二叉树 1、题目 题目链接&#xff1a;226. 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#…

Unity 性能优化之遮挡剔除(Occlusion Culling)(六)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、遮挡剔除是什么&#xff1f;二、静态遮挡剔除的使用步骤1.标记为遮挡剔除对象2.创建Occlusion Area组件3.烘焙4.Occlusion窗口Bake的参数Smallest Oc…

MYSQL基础架构、执行过程分析、事务的实现、索引的选择、覆盖索引

本文是mysql45讲的1-5的总结 文章目录 基础架构连接器分析器优化器执行器SQL查询执行过程详细执行步骤 SQL更新执行过程重要的日志模块&#xff1a;redo log重要的日志模块&#xff1a;binlog阶段性提交 事务事务隔离的实现启动 索引数据库索引模型InnoDB索引组织结构主键选择…

[Unity常见小问题]打包ios后无法修改模型透明度

问题 在Editor下可以使用如下代码去修改模型的材质的透明度&#xff0c;但是打包ios后无法对透明度进行修改且没有任何warning和error using System.Collections; using System.Collections.Generic; using UnityEngine;public class NewBehaviourScript : MonoBehaviour {[R…

订票系统|基于Springboot+vue的火车票订票系统(源码+数据库+文档)

订票系统目录 基于Springbootvue的火车票订票系统 一、前言 二、系统设计 三、系统功能设计 1会员信息管理 2 车次信息管理 3订票订单管理 4留言板管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍…

【RAG 论文】SKR:Self-Knowledge 指导下的 RAG

论文&#xff1a;Self-Knowledge Guided Retrieval Augmentation for Large Language Models ⭐⭐⭐⭐ Tsinghua, arXiv:2310.05002 文章目录 一、论文速读二、实现细节2.1 数据的收集2.2 引出 LLM 的 Self-Knowledge 的方法1&#xff09;Direct Prompting2&#xff09;In-Cont…
最新文章