当前位置: 首页 > news >正文

题解:AcWing 9 分组背包问题

【题目来源】

AcWing:9. 分组背包问题 - AcWing题库

【题目描述】

\(N\) 组物品和一个容量是 \(V\) 的背包。

每组物品有若干个,同一组内的物品最多只能选一个。
每件物品的体积是 \(v_{i,j}\),价值是 \(w_{i,j}\),其中 \(i\) 是组号,\(j\) 是组内编号。

求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。

输出最大价值。

【输入】

第一行有两个整数 \(N,V\),用空格隔开,分别表示物品组数和背包容量。

接下来有 \(N\) 组数据:

  • 每组数据第一行有一个整数 \(S_i\),表示第 \(i\) 个物品组的物品数量;
  • 每组数据接下来有 \(S_i\) 行,每行有两个整数 \(v_{i,j},w_{i,j}\),用空格隔开,分别表示第 \(i\) 个物品组的第 \(j\) 个物品的体积和价值;

【输出】

输出一个整数,表示最大价值。

【输入样例】

3 5
2
1 2
2 4
1
3 4
1
4 5

【输出样例】

8

【解题思路】

image

【算法标签】

《AcWing 9 分组背包问题》 #背包问题# #DP#

【代码详解】

// 引入所有标准库头文件,方便使用各种标准库功能
#include <bits/stdc++.h>// 使用标准命名空间,避免每次使用标准库函数时都需要加 std:: 前缀
using namespace std;// 定义常量
const int N = 110;  // 定义物品最大分组数量为110// 定义全局变量
int f[N][N];          // f[i][j]: 表示只从前i组物品中选,当前总体积不超过j时的最大价值
int v[N][N], w[N][N]; // v[i][j]: 第i组第j个物品的体积,w[i][j]: 第i组第j个物品的价值
int s[N];             // s[i]: 第i组物品的个数
int n, m;             // n: 物品组数,m: 背包容量// 主函数,程序的入口点
int main()
{// 读取物品组数n和背包容量mcin >> n >> m;  // n: 物品组数,m: 背包容量// =============================// 输入部分:读取每组物品的信息// =============================// 外层循环:遍历所有物品组,从第1组到第n组for (int i = 1; i <= n; i++)  // 第i组{// 读取第i组物品的个数cin >> s[i];  // s[i]: 第i组物品的个数// 内层循环:遍历第i组中的每个物品,从第1个到第s[i]个for (int j = 1; j <= s[i]; j++)// 读取第i组第j个物品的体积v[i][j]和价值w[i][j]cin >> v[i][j] >> w[i][j];  // v[i][j]: 第i组第j个物品的体积,w[i][j]: 第i组第j个物品的价值}// =============================// 动态规划部分:计算只从前i组物品中选,总体积不超过j时的最大价值// 类似于0/1背包问题,但针对每组物品进行选择// =============================// 外层循环:遍历所有物品组,从第1组到第n组for (int i = 1; i <= n; i++)  // 类似0/1背包{// 中层循环:遍历所有可能的背包容量,从0到mfor (int j = 0; j <= m; j++) {// 内层循环:遍历当前组i中的每个物品,从第0个到第s[i]个(不选到选s[i]个)for (int k = 0; k <= s[i]; k++) {// 检查当前选择第i组第k个物品是否使得总体积不超过当前背包容量jif (j >= v[i][k]) {// 更新当前状态f[i][j]为选择或不选择第i组第k个物品时的最大价值// f[i][j] = max(f[i][j], f[i-1][j - v[i][k]] + w[i][k])// 解释:// f[i][j] 表示只从前i组物品中选,总体积不超过j时的最大价值// f[i-1][j - v[i][k]] 表示只从前i-1组物品中选,总体积不超过j - v[i][k]时的最大价值(即未选择第i组第k个物品时的状态)// w[i][k] 表示选择第i组第k个物品时的价值// 通过选择或不选择第i组第k个物品,取两者中的最大值来更新f[i][j]f[i][j] = max(f[i][j], f[i - 1][j - v[i][k]] + w[i][k]);}}}}// =============================// 输出结果:在背包容量为m时,选择所有n组物品的最大价值// =============================// 输出f[n][m],即只从前n组物品中选,总体积不超过m时的最大价值cout << f[n][m] << endl;// 程序正常结束,返回0return 0;
}

【运行结果】

3 5
2
1 2
2 4
1
3 4
1
4 5
8
http://www.jsqmd.com/news/409970/

相关文章:

  • 题解:AcWing 4 多重背包问题 I
  • 莱博雷生Lemborexant治疗失眠症的标准睡前给药方案与次日嗜睡风险评估
  • 七里海潮汐表查询2026-02-26
  • 题解:AcWing 894 拆分-Nim游戏
  • 题解:AcWing 892 台阶-Nim游戏
  • Photoroom 2026.08.04 | 法国大厂出品,高质量无限AI生图,最强电商作图
  • 随心听书 2.0.2 | 电子书听书神器,内置微软语音,堪比真人
  • stm32死锁是怎么实现的
  • stm32最级别的烧录解锁是什么?
  • Agentic AI:自主决策的新范式
  • 2026优质的汽车涂装废水处理企业推荐 - 品牌排行榜
  • 2026哪个品牌的袋式过滤器好?行业口碑推荐 - 品牌排行榜
  • Microsoft Agent Framework 取出 DeepSeek 思考内容
  • 从基础到实战:Java全栈开发工程师的面试实录
  • 服务效率提升实战:排队理论与多场景仿真案例
  • 安装开发环境
  • 深入解析Stable Diffusion核心组件:超越基础文本到图像的内部机制
  • 避免在 onbind 方法调用 getCallingUid 与 getCallingPid 方法
  • 好用的skills清单
  • 在 Android Studio 中,新建 AIDL 文件按钮是灰色
  • Android 开发问题:The direction of ‘data‘ is not specified. array can be an in, out, or inout parameter.
  • Android 多进程开发 - AIDL 回调、RemoteCallbackList、AIDL 安全校验
  • 为什么 Controller 层坚决不能直接调 DAO 层?
  • Redis 的 ZipList 是什么?它是怎么解决内存碎片问题的?
  • 小遥搜索v1.2.0版本更新【已支持-语雀数据源集成】
  • 梦笔记20260225
  • 2026年智能系统门窗公司综合评估:五大品牌实力对比 - 2026年企业推荐榜
  • 2026年河南氧系漂白剂直销公司综合评估与精选推荐 - 2026年企业推荐榜
  • 2026年静音系统门窗诚信服务商综合评测与选购指南 - 2026年企业推荐榜
  • 2026年河南道闸广告平台深度盘点与选择指南 - 2026年企业推荐榜