背包九讲——分组背包问题

news2024/11/29 10:37:30

目录

分组背包问题

问题定义

解题算法

问题解法

朴素解法:

一维优化解法

变式题型


背包问题第六讲——分组背包问题

背包问题是一类经典的组合优化问题,通常涉及在限定容量的背包中选择物品,以最大化某种价值或利益。问题的一般描述是:有一个背包,其容量为C;有一组物品,每个物品有重量w和价值v。目标是选择一些物品放入背包,使得它们的总重量不超过背包容量,同时总价值最大。
分组背包问题是背包问题的变体,它的一般描述为对物品进行分组,对每一组内的物品规定只能选择k个。

分组背包问题

分组背包问题(Grouped Knapsack Problem)是组合优化中的一个问题,它是经典的背包问题的变种。在分组背包问题中,有多个物品组,每组中的物品不可分割,并且每组中的物品数量至少有一个。目标是在不超过背包容量的前提下,选择物品的组合,使得总价值最大。

它在一组物品中进行选择,每个物品属于某个特定的组。问题的描述通常是这样的:给定若干组物品,每组物品都有自己的重量、价值以及数量限制。目标是选择若干组物品放入背包中,使得背包中物品的总价值最大。 

问题定义

  • 物品:有 n 组物品,每组有若干个不可分割的物品。
  • 背包容量:背包可以承载的最大重量为 W。
  • 价值:每组物品有一个价值。
  • 重量:每组物品有一个重量。
  • 目标:选择一些组的物品,使得总重量不超过 W,且总价值最大。

解题算法

  1. 动态规划:这是解决分组背包问题最常用的方法。

    状态定义:定义f[i[j]表示考虑前 i 组物品,当前背包容量为 j 时的最大价值。
    • 状态转移方程
      • 如果不选第 i 组物品:f[i][j]=f[i-1][j]
      • 如果选第 i 组物品(前提是 j 至少可以装下第 i 组物品):f[i][j] = max(f[i][j], dp[i-1][j-w[i]] + v[i])
    • 初始化:f[0][j]=0,因为没有物品时价值为0。
    • 遍历顺序:先遍历物品组,再遍历背包容量。
  2. 贪心算法:在某些情况下,如果物品的价值和重量满足某种比例关系,可以使用贪心算法。

  3. 回溯法:尽管效率较低,但可以用来验证问题的解。


问题解法

朴素解法:

这里朴素解法利用的二维数组f[i][j]来进行状态转移,枚举物品组数,枚举体积,枚举对于每组物品的决策,选还是不选,以得到最优解。这里朴素解法不再详细介绍,只放一个代码段,因为后面还可以优化一下。

其实看起来跟多重背包的朴素解法差不多,有什么不同的,下面放上了两段代码,比较看一下。不同在了就是在状态转移上了,多重背包呢可以选多个所以用k来控制,分组背包呢,例题中一组背包中最多只允许选一个,就是对于一组背包可以不选可以选一个。每一个物品都是不同的、有个性的,没有完全相同的,第三个for循环就是在枚举每一组具体的物品。

//多重背包朴素解法
for(int i=1;i<=n;i++){//物品
	for(int j=1;j<=V;j++){//体积
		for(int k=0;k<=s[i];k++){//决策
			if(j>=k*v[i]){
				f[i][j]=max(f[i][j],f[i-1][j-k*v[i]])+k*w[i];
			}
		}
	}
}
cout<<f[n][V]<<endl;

//分组背包朴素解法
for(int i=1;i<=n;i++){//第几组物品
	for(int j=1;j<=V;j++){//体积
		for(int k=0;k<=s[i];k++){//决策
			if(j>=v[i][k]){
				f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
			}
		}
	}
}
cout<<f[n][V]<<endl;

一维优化解法

对照朴素解法,多重背包呢时间复杂度那个for循环k的可以优化掉,空间复杂度也可以优化成一维的,但是时间复杂度优化是有条件的,多重背包呢可以组合进行二进制优化,也可以分类进行单调队列优化。分组背包呢,第i组物品的体积价值都是各不相同的,毫无规律可言,何以优化,但是在空间复杂度上可以优化成一维,f[i][j]是在f[i-1][j]转移过来的,就是在前一组物品决策完转移过来的,只是用了上一行的数据,有点类似01背包的一维优化,我们把此叫做滚动数组,前面的数据我更新完就不需要了,我只需要保存此时状态的数据即可,便于再下一次利用时可以拿来直接用。用完就可以释放掉,后面都不需要了,因此我们可以优化成一维解法。

#include<iostream>
using namespace std;
int dp[1005],v[1005],w[1005];//dp[i]表示背包容量为i时所获得最大价值
int N,V;
int main(){
	cin>>N>>V;
	int p;//p表示第p组物品
	for(int i=1;i<=N;i++){
		cin>>p;
		for(int j=1;j<=p;j++){
			cin>>v[j]>>w[j];
		}
        //因为dp[j]会先于dp[j-v[k]]更新,所以dp[j-v[k]]的值等价于dp[i-1][j-v[k]]
		for(int j=V;j>=1;j--){//逆序枚举背包容量
			for(int k=1;k<=p;k++){
				if(j>=v[k]){
					dp[j]=max(dp[j],dp[j-v[k]]+w[k]);
				}
			}
		}
	}
	cout<<dp[V]<<endl;
	return 0;
}

 注:这里注意枚举背包容量和枚举k顺序不可颠倒,不然dp[j-v[k]]的值就不等价于dp[i-1][j-v[k]]了。


变式题型

博主做过其他类型的题,但都是分组背包的变式。有的题呢,一组物品给你限定了选多少个,比如选2个3个,例题中最多选一个,这样的话就比较麻烦了,既要确定选了哪一组物品又要达到选几个的要求,还是再次基础上,利用贪心,在每一组背包选几个的要求基础上,使得每一组背包都是最优的就可以(01背包)。用背包容量去枚举每一组背包,再去加一个if判断是否达到选几个的要求。有的呢还会把物品乱序输入,让你自己根据输入的编号去分组好,再去进行选择。下面放一个我写过的题的代码,背包的组数打乱,需要自己组合背包这一类的问题(当然题中样例打乱)。

#include<iostream>
#include<vector>
using namespace std;
int w[31],c[31];
int dp[201];
int v,n,p,t;
int main(){
	cin>>v>>n>>t;//v容量n物品t组数
	vector<vector<int>> group(t+1);
	for(int i=1;i<=n;i++){
		cin>>w[i]>>c[i]>>p;//p属于第几组
		group[p].push_back(i);//把下标往里抛就行
	}
	for(int i=1;i<=t;i++){//与一维优化类似
		for(int j=v;j>=0;j--){
			for(int k=0;k<group[i].size();k++){
				int index=group[i][k];
				if(j>=w[index]){
					dp[j]=max(dp[j],dp[j-w[index]]+c[index]);
				}
			}
		}
	}
	cout<<dp[v]<<endl;
	return 0;
}
/*
10 6 3
2 1 1
3 3 1
4 8 2
6 9 2
2 8 3
3 9 3
*/
//20

上篇文章:背包九讲——二维费用背包问题-CSDN博客

分组背包呢,听起来就是分组分组……,无非还是01背包的变形,变形非常多,但是万变不离其宗,方法会了,其他变式也都迎刃而解。博主水平有限,能说的都在文章展现了,有错误的地方请大家指出,大家有疑问的地方随时可以私信我,看到必答。下一篇更新树形背包(有依赖的背包)。

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

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

相关文章

模型 五遍沟通法(企业管理)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。确保信息准确&#xff0c;促进共识。 1 五遍沟通法的应用 1.1 五遍沟通模型案例&#xff1a;新员工入职培训 一家日本科技公司新招聘了一批员工&#xff0c;人力资源部门需要确保新员工对公司的文化…

学习笔记——路由——IP组播-PIM-DM(密集模式)前言概述

7、PIM-DM(密集模式) (1)前言 PIM-DM(PIM Dense Mode)使用“推(Push)模式”转发组播报文&#xff0c;一般应用于组播组成员规模相对较小、相对密集的网络。 在实现过程中&#xff0c;它会假设网络中的组成员分布非常稠密&#xff0c;每个网段都可能存在组成员。当有活跃的组…

Oracle自动处理表空间不足脚本

关注过我的朋友们应该知道我分享过一些常用的监控脚本&#xff0c;其中最常用的就是监控表空间使用率的脚本&#xff0c;具体可以参考如下链接​&#xff1b; oracle常用监控脚本&#xff08;纯干货&#xff0c;没有EMCC,ZABBIX也不怕&#xff09;_oracle 监控及日常处理脚本-…

Jenkins+maven+git(gogs)自动化构建打包+部署(项目实战)

安装Jenkins所需插件 Maven IntegrationPublish Over SSHGit 系统管理>插件管理>Available plugins。在此安装所需要的插件 全部安装完成 配置Jenkins 系统管理>全局配置 JDK配置 这个jdk的目录是Jenkins容器里面的jdk目录&#xff0c;docker安装一般都是这…

提升网站流量和自然排名的SEO基本知识与策略分析

内容概要 在当今数字化时代&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;成为加强网站可见度和提升流量的重要工具。SEO的基础知识包括理解搜索引擎的工作原理&#xff0c;以及如何通过优化网站内容和结构来提高自然排名。白帽SEO和黑帽SEO代表了两种截然不同的策略&a…

uniapp开发小程序【简单的实现点击下拉选择性别功能】

一、展示效果 二、代码 <template><view><view class="form_box"><view class="item"

Flutter 在 对接 google play 时,利用 android studio 可视化生成 已签名的aab包

android studio 可视化生成 aab包 第一 &#xff1a; 先说注意事项 在Flutter项目里面&#xff0c;直接打开当前项目是不行的&#xff0c;不显示相应操作&#xff0c;需要在Android 目录打开&#xff0c;直白点就是直接打开项目里面的Android 目录 不然会出现的一些问题 第一…

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据)

【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff&#xff08;geogrid&#xff0c;WPS所需数据&#xff09; 数据准备&#xff1a;以叶面积指数LAI为例QGis实操&#xff1a;基于GIS4WRF插件将geotiff数据转为tiff警告&#xff1a;GIS4WRF: Input layer had an unexpected …

VictoriaMetrics 中文教程(10)集群版介绍

VictoriaMetrics 中文教程系列文章&#xff1a; VictoriaMetrics 中文教程&#xff08;01&#xff09;简介VictoriaMetrics 中文教程&#xff08;02&#xff09;安装VictoriaMetrics 中文教程&#xff08;03&#xff09;如何配置 Prometheus 使其把数据远程写入 VictoriaMetri…

3D Gaussian Splatting 入门

1 摘要 3D Gaussian Splatting是一种将点云表示为高斯分布&#xff08;Gaussian Distributions&#xff09;的方法&#xff0c;用于3D重建、渲染等领域。这种方法通过在3D空间中对点云进行参数化&#xff0c;使得每个点不仅有位置&#xff08;XYZ坐标&#xff09;&#xff0c;还…

https和http的区别,及HTTPS的工作流程

HTTP&#xff08;HyperText Transfer Protocol&#xff09;和HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff09;都是超文本传输协议&#xff0c;但它们之间的关键区别在于安全性。 安全性&#xff1a; HTTP&#xff1a;数据以明文传输&#xff0c;没有加密&…

Docker | 将本地项目发布到阿里云的实现流程

发布到阿里云 本地镜像发布到阿里云流程具体流程1. docker commit 生成新镜像文件2. 查看镜像3. 阿里云开发者平台选择控制台&#xff0c;进入容器镜像服务&#xff0c;选择个人实例创建命名空间仓库名称进入管理界面获得脚本推送到阿里云 补充&#xff1a; docker tag 命令基本…

基于Pyecharts的数据可视化开发(二)调用通义千问api分析爬虫数据

上一篇博客做了关于“广州市2023年天气情况”的数据爬取&#xff0c;并保存为.csv文件。下一步是想用生成的.csv文件&#xff0c;直接调用大模型api进行分析&#xff0c;得出结论。通过调研&#xff0c;阿里云的通义千问大模型qwen-long可以实现对文件数据的分析。 通义千问大模…

【C++】入门C++

1.C的第一个程序 之前写的C语言文件都是后缀为.c的文件&#xff0c;进入C后就要把后缀改为.c了&#xff0c;vs编译器看到是.cpp就会调⽤C编译器编译。C兼容C语言的绝大多数语法&#xff0c;所以C语言的 hallo word 依旧可以在C下使用。 //test.cpp //c语言的hallo world #inc…

快速上手机器学习-朴素贝叶斯

朴素贝叶斯 引言&#xff1a;本文通过介绍先验概率&#xff0c;后验概率&#xff0c;条件概率计算和贝叶斯定理等概率论内容引入朴素贝叶斯分类算法的基本思路&#xff0c;朴素贝叶斯的最终分类思想是将输入分类给概率最大的类&#xff0c;这也是概率模型算法的共有思想。本文专…

【测试平台】打包 子节点android环境配置

背景 本文记录不是安卓Gradle打包&#xff0c;因为我们google play提审&#xff0c;为了规避跟下架包的相似度避免马甲包封号&#xff0c;使用混淆逻辑。 打包环境部署 申请对应虚拟机会有两个账号root和admin&#xff0c;主要避免root账号权限过高造成脚本误操作。这里面问题…

模型融合新趋势!Transformer领域专家纷纷布局,高分成果轻松达成!

今天给大家分享一个能发A会且不卷的方向&#xff1a;模型融合&#xff01; 光是ICLR2025的投稿&#xff0c;其增长就跃升至前30&#xff0c;可见热度很高&#xff01;但相比其他领域&#xff0c;总量还不大&#xff0c;相对蓝海&#xff0c;创新空间很大。 其所以这么热门&am…

1.机器人抓取与操作介绍-深蓝学院

介绍 操作任务 操作 • Insertion • Pushing and sliding • 其它操作任务 抓取 • 两指&#xff08;平行夹爪&#xff09;抓取 • 灵巧手抓取 7轴 Franka 对应人的手臂 6轴 UR构型去掉一个自由度 课程大纲 Robotic Manipulation 操作 • Robotic manipulation refers…

spark豆瓣书籍推荐系统-计算机毕业设计源码53447

摘要 本论文主要论述了如何基于Spark开发一个豆瓣书籍推荐系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述豆瓣书籍推荐系统的当前背景以及系统开发的目的&#xff0c;后续章节将严…

macOS开发环境配置与应用开发教程

macOS开发环境配置与应用开发教程 引言 macOS是一个强大的操作系统&#xff0c;广泛应用于软件开发&#xff0c;尤其是iOS和macOS应用开发。本文将详细介绍如何配置macOS开发环境&#xff0c;并通过实例演示如何进行应用开发。希望通过这篇文章&#xff0c;帮助读者快速上手m…