【算法】动态规划专题⑧ —— 分组背包问题 python

news/2025/2/9 8:43:46 标签: 算法, 动态规划, python

目录

  • 前置知识
  • 进入正题
  • 实战演练
  • 总结


前置知识


算法动态规划专题⑤ —— 0-1背包问题 + 滚动数组优化 python


进入正题


分组背包问题的详细解析

1. 问题定义

分组背包问题 中,物品被划分为若干组,每组内的物品 互斥(只能选择其中一个或不选)。
给定背包容量 (C),每组物品的价值和重量不同,目标是在不超过背包容量的前提下,最大化总价值。


2. 动态规划状态定义

  • 状态定义
    dp[i][j] 表示前 (i) 组物品,背包容量为 (j) 时的最大总价值。

  • 状态转移方程
    对于第 (i) 组中的每个物品 (k),在容量允许的情况下,选择是否将其加入背包:
    在这里插入图片描述

    其中 w k w_k wk v k v_k vk 是物品 (k) 的重量和价值。


3. 一维数组空间优化

  • 优化思路
    将二维数组压缩为一维数组 dp[j],表示容量为 (j) 时的最大价值。
    为确保每组内物品 只选一个,需 倒序遍历容量(类似01背包)。

  • 转移方程优化
    在这里插入图片描述


4. 算法实现步骤

  1. 输入处理
    读取物品分组信息、背包容量。
  2. 初始化
    一维数组 dp 初始化为全0。
  3. 遍历每组物品
    对每组内的所有物品,逆序更新容量对应的最大价值。
  4. 输出结果
    dp[capacity] 即为最大总价值。

5. 关键点解析

  1. 遍历顺序
    • 外层循环遍历组,保证每组只处理一次。
    • 内层循环逆序遍历容量,确保每组内的物品不会被重复选取。
  2. 时间复杂度
    O(G*C*K),其中 (G) 为组数,(C) 为容量,(K) 为每组最多物品数。
  3. 空间复杂度
    O(C),优化后仅需一维数组。

6. 示例分析

输入

  • 第1组物品:[(2,3), (3,4)]
  • 第2组物品:[(4,5), (1,2)]
  • 背包容量:(5)

执行过程

  • 处理第1组
    • 容量5:可选取物品2(重量3,价值4),更新 dp[5] = max(0, dp[5-3]+4) = 4
    • 容量3:选取物品1(重量2,价值3),dp[3] = 3
  • 处理第2组
    • 容量5:可选取物品4(重量1,价值2),更新 dp[5] = max(4, dp[5-1]+2) = max(4, dp[4]+2)
      其中 dp[4] 在第1组处理后为4(选物品2,重量3,价值4),因此 dp[5] = 4+2 = 6
    • 容量4:选取物品3(重量4,价值5),更新 dp[4] = 5

最终结果
最大价值为 (6)(选第1组的物品2和第2组的物品4)。


实战演练


分组背包问题 https://www.acwing.com/problem/content/9/

题目描述

N N N 组物品和一个容量是 V V V 的背包。
每组物品有若干个,同一组内的物品最多只能选一个。
每件物品的体积是 v i j v_{ij} vij,价值是 w i j w_{ij} wij,其中 i i i 是组号, j j j 是组内编号。
求解
将哪些物品装入背包,使物品总体积不超过背包容量 且总价值最大。

输入格式

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

接下来有 N N N 组数据:

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

输出格式

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

数据范围

0 < N , V ≤ 100 0 \lt N, V \le 100 0<N,V100
0 < S i ≤ 100 0 \lt S_i \le 100 0<Si100
0 < v i j , w i j ≤ 100 0 \lt v_{ij}, w_{ij} \le 100 0<vij,wij100

输入样例

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

输出样例:

8


题解code:

python">n, v = map(int, input().split())
dp = [[0] * (v + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
    si = int(input())
    for _ in range(si):
        vij, wij = map(int, input().split())
        for j in range(0, v + 1):
            if j < vij:
                dp[i][j] = max(dp[i][j], dp[i - 1][j])
            else:
                dp[i][j] = max(dp[i][j], dp[i - 1][j], dp[i - 1][j - vij] + wij)
print(dp[n][v])

优化:

python"># 读入数据
n, v = map(int, input().split())
groups = []
for _ in range(n):
    si = int(input())
    group = [list(map(int, input().split())) for _ in range(si)]
    groups.append(group)

dp = [0] * (v + 1)

for i in range(1, n + 1):
	# 倒序枚举
    for j in range(v, -1, -1):
        for vi, wi in groups[i - 1]:
            if j >= vi:
                dp[j] = max(dp[j], dp[j - vi] + wi)
print(dp[v])


总结


分组背包问题的核心在于 每组内物品的互斥性。通过动态规划的状态转移和一维数组优化,可以在合理的时间复杂度内高效解决问题。
注意遍历顺序和状态更新的逻辑,避免同一组物品被重复选择。


END
如果有更多问题或需要进一步的帮助,可以在评论区留言讨论哦!
如果喜欢的话,请给博主点个关注 谢谢


http://www.niftyadmin.cn/n/5845858.html

相关文章

【PyQt】集中式样式表(QSS文件)管理界面样式

集中式样式表&#xff08;QSS文件&#xff09;管理界面样式 集中式样式表&#xff08;通常使用QSS&#xff0c;Qt StyleSheet&#xff09;是一种非常有效的方式来管理和定制你的PyQt应用程序的界面样式。类似于Web开发中的CSS&#xff0c;QSS允许你以声明式的方式定义组件的外…

android设置添加设备QR码信息

摘要&#xff1a;客户衍生需求&#xff0c;通过扫QR码快速获取设备基础信息&#xff0c;并且基于POS SDK进行打印。 1. 定位至device info的xml添加相关perference Index: vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/my_device_info.xml--- vendor/medi…

Linux strace命令介绍

&#x1f4ca; strace 命令详解 &#x1f680; 1. 什么是 strace&#xff1f; strace&#xff08;System Trace&#xff09;是 Linux 下的一个强大调试工具&#xff0c;用于跟踪和诊断程序与内核之间的交互。它可以捕获程序执行过程中发出的 系统调用&#xff08;System Calls…

TensorFlow 示例平方米转亩(二)

一 训练结果 二 完整代码 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt from tensorflow.keras.callbacks import EarlyStopping# 中文字体设置 plt.rcParams[font.sans-serif] [Microsoft YaHei] plt.rcParams[axes.unicode_minus] Fals…

wordpressAI工具,已接入Deepseek 支持自动生成文章、生成图片、生成长尾关键词、前端AI窗口互动、批量采集等

基于关键词或现有内容生成SEO优化的文章&#xff0c;支持多种AI服务&#xff08;如OpenAI、百度文心一言、智谱AI等&#xff09;&#xff0c;并提供定时任务、内容采集、关键词生成等功能。 核心功能 文章生成 关键词生成&#xff1a;根据输入的关键词生成高质量文章。 内容…

mysql8安装时提示-缺少Microsoft Visual C++ 2019 x64 redistributable

MySQL8.0安装包mysql-8.0.1-winx64进行安装&#xff0c;提示&#xff1a;This application requires Visual Studio 2019 x64Redistributable, Please install the Redistributable then runthis installer again。出现这个错误是因为我们电脑缺少Microsoft Visual C 这个程序&…

BiGRU双向门控循环单元多变量多步预测,光伏功率预测(Matlab完整源码和数据)

代码地址&#xff1a;BiGRU双向门控循环单元多变量多步预测&#xff0c;光伏功率预测&#xff08;Matlab完整源码和数据) BiGRU双向门控循环单元多变量多步预测&#xff0c;光伏功率预测 一、引言 1.1、研究背景和意义 随着全球对可再生能源需求的不断增长&#xff0c;光伏…

分割回文串(力扣131)

这道题咋一看与之前做过的组合问题不相干&#xff0c;实际上仍然需要用上组合问题的模版。分割操作其实就是组合问题里的递归子集并挑选数字。举个例子&#xff1a;我们有一个字符串1,2,3,4,组合问题中我们先在最开始的集合中选择1&#xff0c;然后递归子集2,3,4&#xff0c;这…