代码随想录算法训练营第三十五天|背包问题理论基础、携带研究材料、分割等和子集

news2024/9/20 1:13:17

背包问题理论基础

1.背包问题概述

01背包:有n种物品,每种物品只有一个;

完全背包:有n种物品,每种物品有无限个;

多重背包:有n种物品,每种物品的个数各不相同。

2. 01背包

有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

暴力解法

每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是O(2^n),这里的n表示物品数量。

所以暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来进行优化!

动态规划解法(二维数组)

dp[i][j]的含义:下标为[0,i]之间的物品任取放进容量为j的背包里所能装的最大价值。

递推公式:对于dp[i][j]如果不放物品i所能容纳的最大价值为dp[i-1][j],如果放物品i的最大价值应该等于背包容量减去物品i的容量所能放的最大价值加上物品i的价值:dp[i-1][j-weight[i]]+value[i]。

则取最大值递推公式为:如果当前背包容量装不下物品i则递推公式为dp[i][j]=dp[i-1][j],背包能装下物品i递推公式为dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);

初始化:由递推公式可以看出dp[i][j]是由其上方以及上方左侧的格子推到而来,所以二维数组的第一行和最左边一行需要初始化。最左边一行也就是容量j为0时最大价值为多少那肯定是0,所以dp[i][0]=0,最上面一行表示放入物品0,当容量小于物品0的重量时的格子初始化为0,当容量大于等于物品0重量的格子初始化为物品0的重量。

遍历顺序:两层for循环一层遍历物品,一层遍历背包,顺序可以颠倒,先遍历谁都可以,无非就是一列一列遍历或者一行一行遍历。

携带研究材料 卡码网 46

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main(){
    
    int n,bagWeight;
    cin>>n>>bagWeight;
    
    vector<int> weight(n,0); //存储每件物品所占空间
    vector<int> value(n,0);  //存储每件物品价值
    
    for(int i=0;i<n;i++){
        cin>>weight[i];
    }
    for(int i=0;i<n;i++){
        cin>>value[i];
    }
    
    vector<vector<int>> dp(n,vector<int>(bagWeight+1,0));
    
    for(int j=weight[0];j<=bagWeight;j++){
        dp[0][j]=value[0];
    }
    
    for(int i=1;i<n;i++){
        for(int j=0;j<=bagWeight;j++){
            if(j<weight[i]) dp[i][j]=dp[i-1][j];
            else{
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);
            } 
        }
    }
    cout<<dp[n-1][bagWeight]<<endl;
    
    return 0;
}

一维数组(滚动数组)

使用二维数组填表时,我们发现每一个表格只与它上一行的信息有关,那么我们可以考虑一行一行填表,将二维数组简化为一维数组,for循环遍历物品,第一次填入二维数组的第一行,第二次由第一行的信息推出第二行的信息并覆盖一维数组,以此类推得到二维数组的最后一行。

dp[j]含义:容量为j的背包所能装的最大价值为dp[j]。

递推公式:如果不放物品i则dp[j]=dp[j],放物品i则dp[j]=dp[j-weight[i]]+value[i]。

则递推公式为dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);

初始化:首先考虑对dp[0]初始化,dp[0]表示容量为0的背包所能装的最大价值那肯定是0,所以dp[0]=0。数组其它位置应该初始化为什么呢?根据递推公式可以看出,如果放物品i我们是从dp[j]和dp[j-weight[i]]+value[i]取最大值,所以dp[j]就不能初始化为一个比较大的值否则会把正确结果覆盖,所以初始化dp[j]=0(j>0)。

遍历顺序

首先遍历背包时应该倒叙遍历,如果正序遍历的话,假设此时遍历到j,前面已经是对应二维数组下一行的信息了,而j后面还是对应二维数组上一行的信息,我们继续向后遍历此时就相当于在二维数组中使用同一行前面的格子的信息来推导后面格子的信息(因为dp[j]和dp[j-weight[i]]有关)这样肯定是不对的。所以必须使用倒叙遍历。

为什么必须先遍历物品再遍历背包呢?同样的道理,一维数组应该由二维数组转化一行一行的去填,如果先遍历背包那么一维数组第一个数直接就变成最后一行的数了,再继续向后推导肯定不对的(我是这么理解的不知道对不对)。

携带研究材料一维数组解法

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main(){
    int M,N;
    cin>>M>>N;
    
    vector<int> costs(M);
    vector<int> values(M);
    
    for(int i=0;i<M;i++){
        cin>>costs[i];
    }
    for(int i=0;i<M;i++){
        cin>>values[i];
    }
    vector<int> dp(N+1,0);
    for(int i=0;i<M;i++){
        for(int j=N;j>=costs[i];j--){
            dp[j]=max(dp[j],dp[j-costs[i]]+values[i]);
        }
    }
    cout<<dp[N]<<endl;
    return 0;
}

分割等和子集 leetcode 416

取数组元素如果可以等于数组元素总和的一半,那么这个问题就解决了,而且使用的元素不能重复,可以把本题转化为一个01背包问题。

dp[j]的含义:容量为j的背包可以容纳的最大价值,也就是容量为j的数组容纳元素最大总和。

如何判断背包装满了呢?就是dp[target]=target,其中target=数组总和/2。

递推公式:在本题中重量和价值是相同的都是数组中元素的数值,则

dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]);

初始化:dp[j]=0。

遍历顺序:就是01背包一维数组的遍历顺序,先遍历物品也就是数组中元素,之后倒叙遍历背包也就是target。

求和也可以使用库函数,accumulate(nums.begin(),nums.end(),0);其中0表示从0开始累加。

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        // 总和不会大于20000,背包最大只需要其中一半,所以10001大小就可以了
        vector<int> dp(10001,0);
        int target=0;
        for(int i=0;i<nums.size();i++){
            target+=nums[i];
        }
        if(target%2==1) return  false;
        target=target/2;
        for(int i=0;i<nums.size();i++){
            for(int j=target;j>=nums[i];j--){
                dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]);
            }
        }
        if(dp[target]==target) return true;
        return false;
    }
};

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

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

相关文章

旋转目标数据集制作:roLabelImg的安装和使用

目录 创建roLabelImg环境 安装pyqt5和lxml 下载roLabelImg源码包 使用roLabelImg roLabelImg常用操作指令 标注展示 由于最近一些项目需要标注旋转数据集&#xff0c;在网上找了一些教程&#xff0c;但大多数都显得比较杂乱&#xff0c;因此想把这些重新整理一下&#xf…

汽车免拆诊断案例 | 2013款北京现代悦动车发动机偶尔无法起动

故障现象 一辆2013款北京现代悦动车&#xff0c;搭载G4FC发动机&#xff0c;累计行驶里程约为13.9万km。车主反映&#xff0c;发动机偶尔无法起动着机&#xff0c;断开点火开关&#xff0c;等待一会儿又可以起动着机。 故障诊断 接车后反复试车&#xff0c;当发动机无法起动着…

TS RadiMation®软件EUT监测与控制:抗扰度测试的智能解决方案

随着电子设备在各个领域的广泛应用&#xff0c;确保它们在各种电磁环境中可靠运行变得尤为重要。TS RadiMation软件以其卓越的EUT监测与控制功能&#xff0c;为抗扰度测试提供了一站式智能解决方案。 在本文中&#xff0c;我们将深入探讨TS RadiMation如何通过先进的输入通道配…

【MATLAB第108期】基于MATLAB的fast、vbsa、dynia、eet、glue、pawn、rsa敏感性分析模型合集(无目标函数)【更新中】

【MATLAB第108期】基于MATLAB的fast、vbsa、dynia、eet、glue、pawn、rsa敏感性分析模型合集&#xff08;无目标函数&#xff09;【更新中】 一、FAST&#xff08;Fourier Amplitude Sensitivity Test&#xff09; FAST&#xff08;Fourier Amplitude Sensitivity Test&#…

2024年10大最佳研发工时管理系统推荐

这篇文章介绍了以下几个工具&#xff1a;PingCode、Worktile、无鱼项目工时系统、盖雅工厂、泽众ALM、蓝凌KMS、Forecast、EasyRedmine、Trello、Hubstaff。 在选择研发工时管理系统时&#xff0c;很多人都感到无从下手。市面上的工具五花八门&#xff0c;功能和特点各不相同&a…

专题十四_优先级队列

目录 1046. 最后一块石头的重量 解析 题解 703. 数据流中的第 K 大元素 解析 题解 692. 前K个高频单词 解析 题解 1046. 最后一块石头的重量 1046. 最后一块石头的重量 解析 题解 class Solution { public:int lastStoneWeight(vector<int>& stones) {// 专…

idea 对于mybatis-plus框架JRebelX和XRebel热启动失效问题

1.mybatis-plus不需要使用热启动插件&#xff0c;修改完代码后&#xff0c;直接重新编译一下即可&#xff0c;不需要重启 2.如果是mapper.xml文件&#xff0c;则直接安装JRebel MybatisPlus extension 插件即可完成mapper.xml静态文件更改进行热加载

墨水屏显示颜色过程中的问题,数据和像素值提取比较

软件使用步骤参考 数据数量问题 对于一个单层图片来说&#xff0c;可以分辨率可以使用像素的数量来描述。图片的长宽由多少像素组成就是所说的图片的长宽。这种说法也不太准确&#xff0c;一般人为分辨率越大&#xff0c;约清晰。这种认知是在同样长度中有更多像素&#xff0…

计算机毕业设计 助农产品采购平台 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

HDFS 原理和操作

目录 一、操作1. web工具2.命令行----常用命令3.Java APIJavaAPI创建HDFS目录&#xff0c;获取HDFS修改权限JavaAPI上传和下载数据使用JavaAPI获取HDFS元信息 二、HDFS原理解析1.数据上传2.数据下载 三、HDFS的高级特性1.回收站2.快照3.配额Quota4.安全模式5.权限管理命令行Jav…

Linux系统之部署俄罗斯方块网页小游戏(二)

Linux系统之部署俄罗斯方块网页小游戏(二) 一、小游戏介绍1.1 小游戏简介1.2 项目预览二、本次实践介绍2.1 本地环境规划2.2 本次实践介绍三、检查本地环境3.1 检查系统版本3.2 检查系统内核版本3.3 检查软件源四、安装Apache24.1 安装Apache2软件4.2 启动apache2服务4.3 查看…

动态规划(二)——例题

目录 Help Jimmy 题目 解题思路 神奇的口袋 题目 枚举的解法 递归的解法 动态规划的解法 滑雪 题目 解题思路 解法一 解法二 Help Jimmy 题目 "Help Jimmy" 是在下图所示的场景上完成的游戏&#xff1a; 场景中包括多个长度和高度各不相同的平台。地面是…

使用ResMaskingNet情绪识别模型的预训练文件进行情绪识别

使用ResMaskingNet情绪识别模型的预训练文件进行情绪识别 前言&#xff1a;本文只介绍如何应用ResMaskingNet模型进行情绪识别应用&#xff0c;对于ResMaskingNet的模型架构以及训练过程并不做详细介绍 Paper:https://ieeexplore.ieee.org/document/9411919 Code:https://git…

【Redis学习 | 第1篇】Redis介绍+下载+服务启动与停止

文章目录 1. Redis介绍2. Redis入门2.1 Redis简介2.2 Redis下载2.3 Redis服务启动与停止2.4 redis设置密码2.5 redis 如何支持远程连接 1. Redis介绍 Redis是一个基于内存的 key-value 结构数据库。 基于内存存储&#xff0c;读写性能高适合存储热点数据&#xff08;热点商品、…

大厂进阶四:React源码解析之Fiber架构

本文主要内容&#xff1a; 1、React Concurrent 2、React15架构 3、React16架构 4、Fiber架构 5、任务调度循环和fiber构造循环区别 一、React Concurrent React在解决CPU卡顿是会用到React Concurrent的概念&#xff0c;它是React中的一个重要特性和模块&#xff0c;主要的…

Android Basis - 密钥和ID认证

书读百遍其义自现&#xff0c;知识点多复习&#xff0c;看到的越多&#xff0c;理解的也越是深刻。也许此时我看到的点是点&#xff0c;十天半个月之后回头看时可能就是新的点或者线了&#xff0c;写博客也是&#xff0c;越写越深刻。 遇到KeyAttestation在gms中的错误 在cts…

EVAL长度突破限制

目录 突破15位限制 代码 绕过方式 第一种&#xff08;使用echo执行&#xff09; 第二种&#xff08;使用file_get_content追加文件后进行问件包含&#xff09; 第三种&#xff08;使用usort可变长参数&#xff09; 突破7位限制 第一种&#xff08;可以使用>创建文件…

whistle非常好用的抓包工具

文档&#xff1a; https://wproxy.org/whistle/install.html 总结 这个工具的界面非常好理解&#xff0c;易于使用。 前端开发过程中&#xff0c;经常需要抓包看数据&#xff0c;mock请求数据&#xff0c;mock响应数据&#xff0c;代理线上资源等 这个工具统统可以满足 一、…

【C++二分查找 贪心】792. 匹配子序列的单词数

本文涉及的基础知识点 C二分查找 贪心 LeetCode792. 匹配子序列的单词数 给定字符串 s 和字符串数组 words, 返回 words[i] 中是s的子序列的单词个数 。 字符串的 子序列 是从原始字符串中生成的新字符串&#xff0c;可以从中删去一些字符(可以是none)&#xff0c;而不改变其…

基于PCA-BP的数据多变量回归预测 Matlab代码(多输入单输出)[可显示原始特征贡献率+贡献率排序+累计贡献率]

基于PCA-BP的数据多变量回归预测 Matlab代码&#xff08;多输入单输出&#xff09;[可显示原始特征贡献率] 1.首先通过主成分分析PCA将数据进行降维&#xff0c;会显示原始特征对应的贡献率(不是贡献率排序&#xff0c;不会让你对应不到对应特征)&#xff0c;选取要求为累计贡…