CSP-J/S 复赛算法 背包DP
文章目录
- 前言
- 背包DP的简介
- 问题描述
- 目标
- 解决方法
- 1. **定义状态**
- 2. **状态转移方程**
- 3. **初始化**
- 4. **目标**
- 举个例子
- 动态规划解决背包问题的核心
- DP背包问题示例代码
- 问题描述
- 代码实现
- 核心代码讲解:
- 举例:
- 总结:
- 总结
前言
背包问题是算法竞赛中的经典题型之一,特别是在CSP-J/S(中国信息学奥林匹克竞赛)复赛中,动态规划(DP)解决背包问题是一个常见且基础的重要内容。背包DP问题通过构建状态转移方程,利用「无后效性」这一特性,可以高效地解决一系列组合优化问题。本文将简要介绍如何在背包问题中运用动态规划思想,通过对状态的设计与转移公式的推导,最终求解出最优解。这种方法不仅是算法竞赛中的常见考点,也是在实际应用中有广泛运用的技巧。
背包DP的简介
背包问题(Knapsack Problem)是动态规划(DP)中的经典问题之一,它描述了一个选择物品的最优化问题。背包问题有很多变种,其中最常见的是0-1背包问题。我们以这个为例介绍一下。
问题描述
假设你有一个容量为 (C) 的背包,以及 (n) 件物品。每件物品都有两个属性:
- 重量 (w_i):物品的重量。
- 价值 (v_i):物品的价值。
你需要从这 (n) 件物品中选择若干件装入背包,但不能超过背包的容量 (C)。同时,你希望背包中的物品总价值最大化。每件物品只能被选一次(即「0-1」背包的「0-1」指的是每个物品只能取或者不取,不能分割)。
目标
最大化装入背包的物品的总价值,条件是物品的总重量不超过背包容量。
解决方法
动态规划(DP)可以很好地解决这个问题。我们一步步设计DP的步骤:
1. 定义状态
用 (dp[i][j]) 表示前 (i) 件物品在容量为 (j) 的背包里能够获得的最大价值。
- 例如,(dp[3][5]) 表示用前三件物品在容量为5的背包里能获得的最大价值。
2. 状态转移方程
对第 (i) 件物品,我们有两种选择:
- 不选择这件物品:那么最大价值就是前 (i-1) 件物品在容量 (j) 下的最大价值,表达式为:
d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j] = dp[i-1][j] dp[i][j]=dp[i−1][j] - 选择这件物品:如果当前物品 (i) 的重量 (w_i \leq j),那么我们可以选择它,最大价值就是当前物品价值 (v_i) 加上剩下的背包容量 (j - w_i) 时前 (i-1) 件物品的最大价值,表达式为:
d p [ i ] [ j ] = d p [ i − 1 ] [ j − w i ] + v i dp[i][j] = dp[i-1][j-w_i] + v_i dp[i][j]=dp[i−1][j−wi]+vi
因此,综合这两种情况,状态转移方程为:
d p [ i ] [ j ] = max ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − w i ] + v i ) dp[i][j] = \max(dp[i-1][j], dp[i-1][j-w_i] + v_i) dp[i][j]=max(dp[i−1][j],dp[i−1][j−wi]+vi)
3. 初始化
对于初始状态,若不选任何物品或背包容量为 0,那么最大价值都是 0,因此:
d p [ 0 ] [ j ] = 0 (对于所有的 j ) dp[0][j] = 0 \quad \text{(对于所有的 \(j\))} dp[0][j]=0(对于所有的 j)
d p [ i ] [ 0 ] = 0 (对于所有的 i ) dp[i][0] = 0 \quad \text{(对于所有的 \(i\))} dp[i][0]=0(对于所有的 i)
4. 目标
最终,我们要的解就是 (dp[n][C]),即前 (n) 件物品在背包容量为 (C) 的情况下可以获得的最大价值。
举个例子
假设有 4 件物品,它们的重量和价值如下:
- 物品 1:重量 2,价值 3
- 物品 2:重量 3,价值 4
- 物品 3:重量 4,价值 5
- 物品 4:重量 5,价值 8
背包容量为 8。求解能够装入背包的最大价值是多少?
通过 DP 表的推算,最终可以得出最大价值为 11(选择物品 2 和物品 4,总重量为 3 + 5 = 8,总价值为 4 + 8 = 11)。
动态规划解决背包问题的核心
- 无后效性:当前的状态(选择第几件物品,剩余容量多少)只与之前的状态相关,而不受未来的决策影响。
- 子问题重叠:每一个子问题的解会被多次使用,因此通过 DP 的方式,可以避免重复计算,提高效率。
这种方法非常适合解决背包问题及其他类似的最优化问题。
DP背包问题示例代码
以下是一个用动态规划(DP)解决 0-1背包问题 的 C 语言代码示例,并附上核心代码的讲解。
问题描述
我们有 n
个物品,每个物品有重量 w[i]
和价值 v[i]
。背包的容量为 C
,我们需要选择物品,使得在不超过背包容量的情况下,物品的总价值最大化。
代码实现
#include <stdio.h>#define MAX_N 100 // 物品最大数量
#define MAX_W 1000 // 背包最大容量int dp[MAX_N + 1][MAX_W + 1]; // DP表,保存最大价值int max(int a, int b) {return (a > b) ? a : b;
}int knapsack(int n, int W, int w[], int v[]) {// 初始化DP表,0件物品或容量为0时价值都为0for (int i = 0; i <= n; i++) {for (int j = 0; j <= W; j++) {dp[i][j] = 0;}}// 动态规划,计算最大价值for (int i = 1; i <= n; i++) {for (int j = 0; j <= W; j++) {if (w[i-1] <= j) {// 状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i-1]] + v[i-1])dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i-1]] + v[i-1]);} else {// 如果当前物品重量大于容量,不能选该物品dp[i][j] = dp[i-1][j];}}}// 返回最大价值return dp[n][W];
}int main() {int n = 4; // 物品数量int W = 8; // 背包容量int w[] = {2, 3, 4, 5}; // 每个物品的重量int v[] = {3, 4, 5, 8}; // 每个物品的价值// 调用背包算法int max_value = knapsack(n, W, w, v);printf("最大价值: %d\n", max_value);return 0;
}
核心代码讲解:
-
dp
数组的定义:int dp[MAX_N + 1][MAX_W + 1];
这里的
dp[i][j]
表示前i
件物品在背包容量为j
的时候可以获得的最大价值。dp
的维度是(n+1) x (W+1)
,其中n
是物品数量,W
是背包容量。 -
初始化DP表:
for (int i = 0; i <= n; i++) {for (int j = 0; j <= W; j++) {dp[i][j] = 0;} }
初始状态是没有物品(即
i = 0
)或者背包容量为 0 时(即j = 0
),那么背包中的最大价值显然是 0。这个初始化确保了后续状态转移时有合理的初始值。 -
状态转移方程:
dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i-1]] + v[i-1]);
这是动态规划的核心部分,对于每个物品,我们有两种选择:
- 不选第
i
件物品:此时最大价值和之前一样,即dp[i-1][j]
。 - 选第
i
件物品:此时需要确保物品重量小于等于背包容量(即w[i-1] <= j
),那么最大价值就是当前物品的价值v[i-1]
加上背包剩余容量j - w[i-1]
的最大价值dp[i-1][j - w[i-1]]
。
- 不选第
-
返回结果:
return dp[n][W];
最终我们需要的答案是
dp[n][W]
,即前n
件物品在背包容量为W
时能够获得的最大价值。
举例:
对于输入:
- 物品数量:4
- 背包容量:8
- 物品重量:{2, 3, 4, 5}
- 物品价值:{3, 4, 5, 8}
程序输出:
最大价值: 11
这个结果对应于选择了物品 2 和物品 4,总重量为 3 + 5 = 8,总价值为 4 + 8 = 11。
总结:
这个代码通过动态规划解决 0-1 背包问题的核心在于状态转移方程,它通过子问题的解来推导出全局问题的最优解。每个子问题的解被存储在 dp
数组中,从而避免重复计算,极大地提高了效率。
总结
背包DP算法通过构建一个DP表格,依次推算每个子问题的最优解,最终得出整个问题的最优解。核心在于合理设计状态和状态转移方程,使得每一步的选择都依赖于之前的子问题结果。在CSP-J/S复赛中,背包问题的灵活变化考验选手对动态规划思想的掌握,理解其原理后能够有效提升问题解决的效率。熟练掌握背包问题的动态规划方法,不仅能够应对竞赛中的挑战,更能为更复杂的优化问题打下坚实基础。
相关文章:

CSP-J/S 复赛算法 背包DP
文章目录 前言背包DP的简介问题描述目标解决方法1. **定义状态**2. **状态转移方程**3. **初始化**4. **目标**举个例子动态规划解决背包问题的核心 DP背包问题示例代码问题描述代码实现核心代码讲解:举例:总结: 总结 前言 背包问题是算法竞…...

如何评估和部署 IT 运维系统?
如何才能将如此新兴、流行的技术转化为企业中实用的系统环境呢? 为此,我们采访了一家已经成功部署IT运维体系的大型企业的IT总监龙先生,请他给我们讲一下企业应该如何真正评估和部署自己的IT运维体系。 真理就是价值。 1.评估选择…...

正态分布的极大似然估计一个示例,详细展开的方程求解步骤
此示例是 什么是极大似然估计 中的一个例子,本文的目的是给出更加详细的方程求解步骤,便于数学基础不好的同学理解。 目标 假设我们有一组样本数据 x 1 , x 2 , … , x n x_1, x_2, \dots, x_n x1,x2,…,xn,它们来自一个正态分布 N…...

s7-200SMART编程软件下载
1、官网: STEP 7 Micro/WIN SMART V2.2 完整版http://w2.siemens.com.cn/download/smart/STEP%207%20MicroWIN%20SMART%20V2.2.zip STEP 7 Micro/WIN SMART V2.3 完整版http://w2.siemens.com.cn/download/smart/STEP%207%20MicroWIN%20SMART%20V2.3.iso STEP 7 Mi…...

Linux驱动开发常用调试方法汇总
引言:在 Linux 驱动开发中,调试是一个至关重要的环节。开发者需要了解多种调试方法,以便能够快速定位和解决问题。 1.利用printk 描述: printk 是 Linux 内核中的一个调试输出函数,类似于用户空间中的 printf。它用于…...

将列表中的各字符串sn连接成为一个字符串s使用;将各sn间隔开os.pathsep.join()
【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 将列表中的各字符串sn 连接成为一个字符串s 使用;将各sn间隔开 os.pathsep.join() [太阳]选择题 下列说法中正确的是? import os paths ["/a", "/b/c", "/d&q…...

算法题总结(八)——字符串
531、反转字符串二 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。 如果剩余字符少于 k 个,则将剩余字符全部反转。如果剩余字符小于 2k 但大于或等于 k 个,…...

大数据开发--1.2 Linux介绍及虚拟机网络配置
目录 一. 计算机入门知识介绍 软件和硬件的概述 硬件 软件 操作系统概述 简单介绍 常见的系统操作 学习Linux系统 二. Linux系统介绍 简单介绍 发行版介绍 常用的发行版 三. Linux系统的安装和体验 Linux系统的安装 介绍 虚拟机原理 常见的虚拟机软件 体验Li…...

2024CSP-J复赛易错点
低级错误 不开long long见祖宗写代码要有输入,别没写输入就交写完代码要在本地测试,多想写极端测试数据,或对拍注意考官说文件夹怎么建,别文件夹建错,爆0别忘写freopen或忘给freopen去注释记着把.exe文件删掉考试时不…...

pytorch 与 pytorch lightning, pytorch geometric 各个版本之间的关系
主要参考 官方的给出的意见; 1. pytorch 与 pytorch lightning 各个版本之间的关系 lightning 主要可以 适配多个版本的 torch; https://lightning.ai/docs/pytorch/latest/versioning.html#compatibility-matrix; 2. pytorch 与 pytorch geometric 各…...

Spring Boot项目的创建与使用
1.通过IDE创建Spring Boot项目 2.目录结构 3.新建TestController控制器 Controller public class TestController {RequestMapping("/test")public ModelAndView test(RequestParam(name "name", defaultValue "刘德华") String name){ModelA…...

pytorch常用函数view、sum、sequeeze、cat和chunk
文章目录 view()函数sequeeze和unsequeezecat和chunk函数sum函数view()函数 view()相当于reshape、resize,重新调整Tensor的形状。 指定调整形状之后的维度import torch re = torch.tensor([1, 2, 3, 4, 5...

【STM32开发之寄存器版】(四)-独立看门狗IWDG
一 、前言 独立看门狗简介: STM32F103ZET6内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备(独立看门狗和窗口看门狗)可用来检测和解决由软件错误引起的故障。 独立看门狗主要性能: 自由运行的递减计数器时钟…...

【S32K3 RTD MCAL 篇1】 K344 KEY 控制 EMIOS PWM
【S32K3 RTD MCAL 篇1】 K344 KEY 控制 EMIOS PWM 一,文档简介二, 功能实现2.1 软硬件平台2.2 软件控制流程2.3 资源分配概览2.4 EB 配置2.4.1 Dio module2.4.2 Icu module2.4.4 Mcu module2.4.5 Platform module2.4.6 Port module2.4.7 Pwm module 2.5 …...

华为OD机试真题---绘图机器(计算面积)
题目描述 绘图机器的绘图笔初始位置在原点(0,0),机器启动后按照以下规则绘制直线: 尝试沿着横线坐标正向绘制直线直到给定的终点E。期间可以通过指令在纵坐标轴方向进行偏移,offsetY为正数表示正向偏移,为负数表示负向偏移。 给…...
HarmonyOs 查看官方文档使用弹窗
1. 学会查看官方文档 HarmonyOS跟上网上的视频学习一段时间后,基本也就入门了,但是有一些操作网上没有找到合适教学的视频,这时,大家就需要养成参考官方文档的习惯了,因为官方的开发文档是我们学习深度任何一门语言或…...

uniapp+Android智慧居家养老服务平台 0fjae微信小程序
目录 项目介绍支持以下技术栈:具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是:数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 老年人 登…...

在一台电脑上实现网页与exe程序使用udp通信
要在同一台电脑上实现网页(前端)与 EXE 程序(后端)通过 UDP 通信,可以使用以下步骤。前端可以使用 JavaScript 通过 WebSocket 与自定义服务器进行通信,该服务器通过 UDP 发送和接收数据,再与 E…...

基于Java的GeoTools对Shapefile文件属性信息深度解析
目录 前言 一、Shapefile的属性列表信息 1、属性表格信息 2、属性表格包含的要素 二、GeoTools对属性表格的解析 1、常规解析方法 2、基于dbf文件的属性信息读取 三、总结 前言 ESRI Shapefile(shp),或简称shapefile,是美…...

付费计量系统实体和接口(1)
13.System entities and interfaces 系统实体和接口 See also Clause 4 for a discussion on general concepts and Clause 5 for generic entity model. 参见条目 4 讨论总体概念、条目 5 通用实体模型。 An entity specification should specify the embodied functions and …...

网易博客旧文----bacnet学习系列之四----VTS的初步使用
bacnet学习系列之四----VTS的初步使用 2014-02-07 13:32:28| 分类: BACnet | 标签: |举报 |字号大中小 订阅 这是一个测试用 的工具,而且是开放源码的,下载地址为:VTS下载官网 也可以从我的网盘下载 VTS下载 我用的是…...

SpringIoC容器的初识
一、SpringIoC容器的介绍 Spring IoC 容器,负责实例化、配置和组装 bean(组件)。容器通过读取配置元数据来获取有关要实例化、配置和组装组件的指令。配置元数据以 XML、Java 注解或 Java 代码形式表现。它允许表达组成应用程序的组件以及这…...

队列的实现与讲解
一.概念与结构 1.概念 只允许在⼀端进行插⼊数据操作,在另⼀端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进⾏插⼊操作的⼀端称为队尾 出队列:进⾏删除操作的⼀端称为队头 注意&…...

hbuilderx+uniapp+Android健身房管理系统 微信小程序z488g
目录 项目介绍支持以下技术栈:具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是:数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 用户功能…...

自动驾驶-参考线生成
为什么要进行参考线生成? apollo在routing模块,已经得到的全局路径,但是其不能直接作为局部路径规划的参考线,这是因为: routing给出的全局路径过长;routing是基于高精地图给出的路径,高精地图…...

厂商资源分享网站
新华三(H3C)是一家中国知名的网络设备供应商,提供网络设备、网络解决方案和云计算服务。公司成立于2003年,是华为公司和惠普公司合资的企业,总部位于中国深圳。 华为(Huawei)是一家全球知名的电…...

【ONE·Web || HTML】
总言 主要内容:HTML基本知识入门,主要介绍了常见的一些标签使用,以及简单案例演示。 文章目录 总言0、前置说明1、认识HTML1.1、是什么1.2、初识 HTML 标签、HTML 文件基本结构1.2.1、相关说明1.2.2、vscode如何快速生成代码 2、HT…...

MongoDB的安装与增删改查基本操作
MongoDB是一种非关系型数据库,是NoSQL语言,但是又是最接近关系型数据库的。内部存储不是表结构,但是可以对数据进行表结构的操作。 一、安装 在官网:Download MongoDB Community Server | MongoDB下载系统对应的版本进行安装即可 二、编辑器 在安装MongoDB后会自带一个编…...

Python水循环标准化对比算法实现
🎯要点 算法区分不同水循环数据类型:地下水、河水、降水、气温和其他,并使用相应标准化降水指数、标准化地下水指数、标准化河流水位指数和标准化降水蒸散指数。绘制和计算特定的时间序列比较统计学相关性。使用相关矩阵可视化集水区和显示空…...

【TypeScript】知识点梳理(一)
#国庆快乐!来点干货~ # #项目中团队总结生产问题,40%是类型相关问题,可见TS的重要性与向好趋势# TS是JS的超集 类型 Number、String、Boolean 首字母大小写,类型有区别,譬如: string是基元(原始…...