完全背包理论基础

news2024/11/20 2:23:49

目录

一.理论基础

 二.遍历顺序问题

2.1 01背包

2.2完全背包

3.相关题型

3.1零钱兑换

3.1.数组总和IV


一.理论基础

题目描述:

有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。

例如,假设背包的最大重量是4

 先来看下01背包问题的核心代码:

for (int i = 0; i < weight.size(); i++) // 遍历物品
{                                 
    for (int j = bagWeight; j >= weight[i]; j--) 
   {
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); // 遍历背包容量
    }
}

这是一维dp数组,因为每个物品只能够放一次,所以在遍历背包容量时要从大到小去遍历。这就很容易想到了,在遍历完全背包时,由于每个相同物品可以放入多次,所以再遍历背包容量时应该从小到大去遍历。例如:

for (int i = 0; i < weight.size(); i++) // 遍历物品
{                                 
    for (int j = weight[i]; j <=bagweight; j++) 
   {
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); // 遍历背包容量
    }
}

 二.遍历顺序问题

2.1 01背包

先简单说下01背包遍历的顺序问题。当使用二维数组去遍历的时候,遍历背包容量时是从小到大遍历的。例如:(当时是先遍历物品,再遍历背包)

 用二维数组时,也是可以先遍历背包容量,再去遍历物品。每次遍历所要用到的数据都是来自当前位置的左上角(包括左边和正上边)。虽然两个for循环遍历的次序不同,但是dp[i][j]所需要的数据就是左上角,根本不会影响dp[i][j]公式的推导 。例如:

for (int j = 0; j <= bagWeight; j++)      // 遍历背包容量
{                   
	for (int i = 1; i < weight.size(); i++)   // 遍历物品
	{                                    
		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]);
	}
}

如果用一维数组呢?

前面已经说了,用一维数组模拟01背包问题时,遍历背包容量时是要从大到小去遍历,才能确保每个物品放了一次。(前面是先遍历物品,后面遍历背包的),那么遍历顺序是否可以改变呢?

答案肯定不能,例如:

 会发现每次背包只放了一个物品。

2.2完全背包

先看一维数组的遍历顺序,前面是先遍历物品,在遍历背包容量(遍历背包容量时是从小到大,才能确保同一个物品可以放入多次)。

例如:

for (int i = 0; i < weight.size(); i++) // 遍历物品
{                                 
    for (int j = weight[i]; j <=bagweight; j++) 
   {
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); // 遍历背包容量
    }
}

遍历顺序:

 如果先遍历背包容量,再去遍历物品也是可以的:

代码:

for (int j = 0; j <= bagWeight; j++) // 遍历背包容量
{
	for (int i = 0; i < weight.size(); i++)// 遍历物品
	{ 
		if (j - weight[i] >= 0) 
           dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
	}
}

3.相关题型

3.1零钱兑换

题目描述:

给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。

请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。

假设每一种面额的硬币有无限个。

例如:

输入:amount = 5, coins = [1, 2, 5]
输出:4
解释:有四种方式可以凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

思路:硬币的面额对应的是物品,凑成的总金额是背包容量。问把背包容量放满,有几种组成方式。价值对应的就是不同的组合方式。例如:

 

 那么初始化时将dp[0]初始化为1即可。注意(上面是先遍历物品,再遍历背包)

代码:

class Solution {
public:
    int change(int amount, vector<int>& coins) {
        vector<int>dp(amount+1,0);
        dp[0]=1;
        for(int i=0;i<coins.size();i++)
        {
            for(int j=1;j<=amount;j++)
            {
                if(j>=coins[i])//说明当前可以有一种组合满足,此时背包容量为j,刚好放满
                {
                    dp[j]+=dp[j-coins[i]]; //当前的组合数+背包容量为j-coins[i] 的组合数
                }
            }
        }
        return dp[amount];  //遍历完所有物品

    }
};

先遍历背包容量,再遍历物品可以么?还是看图,其实算出的是排列数(也就是面额顺序不同即可)

 

3.1.数组总和IV

题目描述:

给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。

例如:

输入:nums = [1,2,3], target = 4
输出:7
解释:
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

跟上面那题一样的吧,不过求的是排列数,直接上代码吧

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        vector<double> v(target+1,0);
        v[0]=1;
        for(int i=1;i<=target;i++)  //先遍历背包
        {
            for(int j=0;j<nums.size();j++)  //再遍历物品
            {
                if(i>=nums[j])
                 v[i]+=v[i-nums[j]];
            }
        }
        return v[target];
    }
};

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

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

相关文章

重置Entity Framework Core的数据迁移

本文主要参考文章重置EntityFramework数据迁移到洁净状态&#xff0c;感谢哈~。可能是版本问题&#xff0c;文中所述操作跟我稍微有所出入&#xff0c;故在此做下记录。注意&#xff0c;本人的IDE是JetbrainsRider&#xff0c;并非Visual Studio&#xff0c;但主要操作是通用的…

Spring事务源码解析

Spring事务源码解析一、基本概念1、ACID属性2、事务的隔离级别3、事务行为4、Spring事务的传播级别5、Spring事务支持方式二、Spring事务的执行源码1、事务AOP2、事务处理拦截器TransactionInterceptor2.1 主要流程2.2 尝试创建事务2.3 清除线程事务信息2.4 事务提交2.5 事务异…

品牌控价、淘宝控价、拼多多控价,如何有效利用平台投诉

低价链接&#xff0c;是品牌渠道管控最重要的工作&#xff0c;同时&#xff0c;也是最难的&#xff0c;尤其是非授权低价链接&#xff0c;不受经销管理制度约束&#xff0c;极可能屡次沟通仍不配合整改&#xff0c;进行平台投诉&#xff0c;也不被平台支持诉求。 确实&#xf…

高级ACL的基础配置命令

ACL概述 ACL是由一系列permit或deny语句组成的、有序规则的列表。 ACL是一个匹配工具&#xff0c;能够对报文进行匹配和区分。 ACL的组成 CL由若干条permit或deny语句组成。每条语句就是该ACL的一条规则&#xff0c;每条语句中的permit或deny就是与这条规则相对应的处理动作。…

各社区文艺团队疫情首秀演出《金龄会》受邀提供全程服务

疫情放开后&#xff0c;各地活动逐渐恢复&#xff0c;受到广州各社区的中老年文艺团队邀约&#xff0c;广东省金龄会于1月9日在金龄会演播厅举办了疫情后的首秀——“健康广东&#xff0c;抗疫成功&#xff0c;再创辉煌”广东中老年文化艺术大赛&#xff0c;由广东省健康金龄公…

MAC(m1)-CentOS8 Docker安装MySQL

1、查看可用的MySQL版本 访问 MySQL 镜像库地址&#xff1a;Docker 查看老版本&#xff1a; 2、拉取MySQL镜像 我们可以拉取官方的最新版本的镜像&#xff1a; docker pull mysql:latest 我的MAC m1安装的mysql是8&#xff0c;准备在虚拟机上安装5.7 没找到哦&#xff0c;呜…

MySQL高级篇第01章(Linux下MySQL的安装与使用)

CentOS环境的准备 虚拟机的克隆 mac地址 主机名 ip地址 UUID 查看是否安装过MySQL 如果是用rpm安装&#xff0c;检查一下RPM PACKAGE rpm -qa | grep -i mysql # -i 忽略大小写检查mysql service服务&#xff1a; systemctl status mysqld.service如果存在mysql-libs的旧…

Vue2.0开发之——Vue组件-生命周期(37)

一 概述 了解生命周期和生命周期函数的概念初步了解组件创建的过程了解beforeCreate和Created生命周期函数的特点了解beforeMount和mounted生命周期函数组件运行阶段的生命周期函数组件销毁阶段的生命周期函数 二 了解生命周期和生命周期函数的概念 2.1 生命周期&生命周期…

李宏毅ML-机器学习任务功略

文章目录机器学习任务功略机器学习框架训练模型通用指南1. training loss is large2. training loss is small2.1 training loss is small and testing loss is large2.2 training loss is small and testing loss is small3. 偏差与复杂度的平衡机器学习任务功略 机器学习框架…

Yolov5训练自己的数据集

一、从官网下载最新的yolov5代码二、新建VOCData文件夹三、VOCData文件夹结构新建Annotations文件夹&#xff0c;存放标签简单的xml文件&#xff0c;应该长这样复杂的xml文件&#xff0c;应该长这个样子新建images文件夹&#xff0c;存放图片数据注意&#xff1a;需要观察自己的…

1.1.2半导体二极管的结构、工作原理、参数、伏安特性;

1.结构 内部实际上是一个PN结&#xff0c;将电极引线和其封装在一起就构成了二极管 拓展&#xff1a;点接触型二极管&#xff0c;面接触型二极管 2.工作原理 3.参数&#xff08;以肖特基二极管SS56为例&#xff09; MAX Forward Voltage(最大导通电压) &#xff0c;因为SS5…

Jvm-hotspot 总结系列-完整版(1)类加载器

一、类加载器子系统的作用&#xff08;1&#xff09;类加载器子系统负责从文件系统或网络中加载class文件&#xff0c;class文件在文件开头有特定的文件标识&#xff08;cafebabe&#xff09;咖啡宝贝。&#xff08;2&#xff09;ClassLoader只负责class文件的加载&#xff0c;…

广告业务系统 之 核心通道 —— “日志中心-s2s监测上报”

文章目录广告业务系统 之 核心通道 —— “日志中心-s2s监测上报”s2s 监测上报s2s 、c2s曝光/互动/Win数据上报监测上报AB 实验平台广告业务系统 之 核心通道 —— “日志中心-s2s监测上报” s2s 监测上报 s2s 监测上报&#xff0c;是 ADX 将广告的曝光、互动[点击/播放/下载…

赛事推荐 | 建筑物细粒度实例分割——2023 IEEE GRSS 数据融合赛道1

1. 赛题名称 建筑物检测和屋顶类型分类 2. 赛题背景 该轨道侧重于从高分辨率卫星光学图像和 SAR 图像中检测和分类建筑物屋顶类型。SAR 和光学模态有望提供补充信息。给定的数据集涵盖了全球六大洲的十七个城市。分类任务由 12 种细粒度的预定义屋顶类型组成。图 1 显示了一…

缺乏长线思考是扼杀工程师前途的屠刀.

缺乏长线思考是扼杀工程师前途的屠刀。 死局 工作几年后&#xff0c;最容易陷入一个隐形的死局&#xff0c;开发只关注实现需求&#xff0c;运维只关注部署、故障。待到七八年&#xff0c;一定会出现后继无力。被替代&#xff0c;早晚而已。 我相信很多领导都讲过沉淀方法论&am…

RK3399平台开发系列讲解(内核调试篇)如何使用perf进行性能优化

🚀返回专栏总目录 文章目录 一、perf list命令二、perf record/report命令三、perf stat命令四、perf top命令五、火焰图沉淀、分享、成长,让自己和他人都能有所收获!😄 📢perf 可以在 CPU Usage 增高的节点上找到具体的引起 CPU 增高的函数,然后我们就可以有针对性地…

开源PPP软件PRIDE-PPPAR使用记录(一)GFZRNX预处理

我们使用PRIDE-PPPAR软件对GNSS观测数据进行解算时&#xff0c;会遇到观测文件不能识别的问题。观测文件不能识别的主要原因是格式不对&#xff0c;可通过GNSS预处理软件进行修复。本文介绍一款由德国波兹坦地学研究中心&#xff08;GFZ&#xff09;开发的GNSS预处理软件GFZRNX…

Mathorcup数学建模竞赛第六届-【妈妈杯】B题:车位分布的优化设计与评价(附一等奖获奖论文、lingo和matlab代码)

赛题描述 随着现代社会经济的快速发展,房地产成为国家经济发展中重要的经济增长点之一。而小区内汽车停车位的分布对于小区居民的上下班出行影响很大。请建立数学模型,解决下列问题: 问题1:分析评判小区汽车停车位分布是否合理的几个关键指标,建立评判车位分布合理的数学…

Qt之单选按钮和复选按钮(QRadioButton、QCheckBox)

文章目录QRadioButton属性示例代码&#xff1a;QCheckBox属性示例代码QRadioButton QRadioButton片这个按钮类应对多选一的场景。打开windows的画图软件&#xff0c;我们就可以看到下面的&#xff1a; 如果我们刚开始的是线&#xff0c;然后我们又想画矩形&#xff0c;则线这…

作用域、生命期和程序的组织结构

一、局部变量和全局变量 在函数内部或复合语句中定义的变量&#xff0c;称为局部变量&#xff08;local variable&#xff09;。 &#xff08;1&#xff09;在一个函数内部定义的变量&#xff1b; &#xff08;2&#xff09;函数的形式参数&#xff1b; &#xff08;3&…