「动态规划::背包」01背包 / AcWing 2(C++)

概述

AcWing 2:

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。

第 i 件物品的体积是 v[i],价值是 w[i]。

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

输入格式

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

接下来有 N 行,每行两个整数用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式

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

数据范围

0<N,V≤10000<N,V≤1000
0<vi,wi≤10000<vi,wi≤1000

输入样例
4 5
1 2
2 4
3 4
4 5
输出样例:
8

背包DP是非常经典的动态规划问题,而01背包更是典中典问题。

之所以称为01背包,是因为每个物品只有选与不选两种状态。


思路

dp就不得不由状态定义和子问题分解,我们来思索一下。

 定义dp[a][b]为能够物品选择范围为[0, a]且当前背包最多能装体积为b的物品总量时的最优解。

这样,我们就可以从小问题推导出大问题的解,应该是这样的:

考虑选择范围为前i个物品,体积为j,有选与不选两种状态,取两种情况最大值。

即dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);

如果 j < v[i],则代表放不下这个物品,dp[i][j] = dp[i - 1][j];


解题过程

我们可以得到非常直观的二重循环。

int solve(){for (int i = 1; i <= n; i++)for (int j = 0; j <= m; j++) {if (j < v[i]) dp[i][j] = dp[i - 1][j];else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);}return dp[n][m];
}

优化方案

背包dp有着非常知名的空间优化。

观察状态转移,可以发现:空间可以被优化成1维的。

我们不再用i存储当前的可选范围信息,取而代之的是,这个信息隐式地蕴含在每次循环中。 

int solve(){for (int i = 1; i <= n; i++)for (int j = m; j >= v[i]; j--) {dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}return dp[m];
}

这里有一个非常重要的行为:倒序枚举j。

我们要保证dp来自于上一个i,即不能污染状态转移的数据源,考虑到 j 来自j - v[i],我们倒序枚举j,就使得j - v[i]不会被j污染。

形象的说

状态转移的方向是从前向后->,如果更新顺序是从后向前<-,那么每个状态获得的新值都不来自这次更新,而是上次。

这样一来,我们可以保证在计算当前(i)dp[j]时,使用的是上次(i - 1)dp[j],这样就等效于二维数组了。

Code

#include <bits/stdc++.h>
using namespace std;
constexpr int N = 1005;
int v[N], w[N];
int dp[N];
int n,m;
int solve(){for (int i = 1; i <= n; i++)for (int j = m; j >= v[i]; j--) {dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}return dp[m];
}
int main(){cin >> n >> m;for (int i = 1; i <= n; i++)cin >> v[i] >> w[i];cout << solve();return 0;
}

复杂度

时间复杂度: O(nm) //需求解n*m个状态。

空间复杂度: O(n)    //预留dp数组空间

总结

背包问题是非常经典的动态规划问题,后续将讲解完全背包、分组背包等更进一步的问题。

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

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

相关文章

Java 中的 设计模式详解

一&#xff1a;设计模式概述 &#xff08;1&#xff09;概述 &#xff08;2&#xff09;分类 创建型 行为型 结构型 二&#xff1a;软件设计模式 2.1 开闭原则 &#xff08;1&#xff09;定义 在程序需要进行拓展的时候&#xff0c;不能修改原有代码 使用到接口和抽象类&#x…

阿里qiankun微服务搭建

主服务 chat vue3 ts vite 子服务 ppt react 18 vite 子服务 agent 主服务 npm i vite-plugin-qiankun mian.ts import ./style/base.scss import virtual:svg-icons-register import { createApp } from vue import { createPinia } from piniaimport App from ./App.vue im…

安装WSL2,配置Ubuntu图像化界面

目录 一、前言二、安装WSL三、安装图像化界面四、参考 一、前言 Windows 子系统下的 Linux 子系统&#xff08;WSL&#xff0c;Windows Subsystem for Linux&#xff09;是微软推出的一项功能&#xff0c;允许用户在 Windows 系统中原生运行 Linux 环境&#xff0c;无需安装虚…

图像畸变-径向切向畸变实时图像RTSP推流

实验环境 注意&#xff1a;ffmpeg进程stdin写入两张图片的时间间隔不能太长&#xff0c;否则mediamtx会出现对应的推流session超时退出。 实验效果 全部代码 my_util.py #进度条 import os import sys import time import shutil import logging import time from datetime i…

Redis Sentinel 和 Redis Cluster 各自的原理、优缺点及适用场景是什么?

我们来详细分析下 Redis Sentinel (哨兵) 和 Redis Cluster (集群) 这两种方案的原理和使用场景。 Redis Sentinel (哨兵) 原理: Sentinel 本身是一个或一组独立于 Redis 数据节点的进程。它的核心职责是监控一个 Redis 主从复制 (Master-Slave) 架构。多个 Sentinel 进程协同…

基于机器学习的电影票房预测

目录 摘 要(完整下载链接附在文末) Abstract 1 绪 论 1.1 研究背景概述 1.2 国内外相关领域研究进展 1.3 电影票房预测技术概览 1.3.1 利用人口统计学特征的方法 1.3.2 基于机器学习的预测模型 2 机器学习相关理论介绍与分析 2.1 机器学习算法理论 2.1.1卷积…

SVMSPro平台获取HTTP-FLV规则

SVMSPro平台获取HTTP-FLV规则 HTTP-FLV的服务端口为&#xff1a;53372&#xff0c;如需要公网访问需要开启这个端口 这里讲的是如何获取长效URL&#xff0c;短效&#xff08;时效性&#xff09;URL也支持&#xff0c;下回讲 一、如何获取HTTP-FLV实时流视频 http://host:po…

ARM架构的微控制器总线矩阵

在 ARM 架构的微控制器&#xff08;MCU&#xff09;中&#xff0c;总线矩阵&#xff08;Bus Matrix&#xff09; 是总线系统的核心互连结构&#xff0c;负责协调多个主设备&#xff08;如 CPU、DMA、以太网控制器等&#xff09;对多个从设备&#xff08;如 Flash、SRAM、外设等…

AI赋能金融:智能投顾、风控与反欺诈的未来

AI赋能金融&#xff1a;智能投顾、风控与反欺诈的未来 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 AI赋能金融&#xff1a;智能投顾、风控与反欺诈的未来摘要引言一、智能投顾&#xff1a;从经验驱动到人机协同…

【机器学习】朴素贝叶斯

目录 一、朴素贝叶斯的算法原理 1.1 定义 1.2 贝叶斯定理 1.3 条件独立性假设 二、朴素贝叶斯算法的几种常见类型 2.1 高斯朴素贝叶斯 (Gaussian Naive Bayes) 【训练阶段】 - 从数据中学习模型参数 【预测阶段】 - 对新样本 Xnew​ 进行分类 2. 2 多项式朴素贝叶斯 (…

鸿蒙 ArkTS 组件 通用事件 通用属性 速查表

ArkTS 组件 组件 通用事件 速查表 通用事件事件名称简要说明点击事件onClick(event: Callback<ClickEvent>, distanceThreshold: number): T相较于原有 onClick 接口&#xff0c;新增 distanceThreshold 参数作为点击事件移动阈值&#xff0c;当手指的移动距离超出所设…

Java云原生+quarkus

一、Java如何实现云原生应用&#xff1f; 传统的 Java 框架&#xff08;如 Spring Boot&#xff09;虽然功能强大&#xff0c;但在云原生场景下可能显得笨重。以下是一些更适合云原生的轻量级框架&#xff1a; Quarkus(推荐) 专为云原生和 Kubernetes 设计的 Java 框架。支持…

C语言教程(二十三):C 语言强制类型转换详解

一、强制类型转换的概念 强制类型转换是指在程序中手动将一个数据类型的值转换为另一种数据类型。在某些情况下,编译器可能不会自动进行类型转换,或者自动转换的结果不符合我们的预期,这时就需要使用强制类型转换来明确指定要进行的类型转换。 二、强制类型转换的语法 强制类…

Spring Boot × K8s 监控实战-集成 Prometheus 与 Grafana

在微服务架构中&#xff0c;应用的可观测性至关重要。Kubernetes 已成为容器化部署的标准&#xff0c;但其自身的监控能力有限&#xff0c;需要与其他工具集成才能实现详细的运行数据采集与分析。 本文将通过 Spring Boot Kubernetes Prometheus Grafana 实战&#xff0c;打…

phpstudy修改Apache端口号

1. 修改Listen.conf文件 本地phpstudy安装目录&#xff1a; 2.其他问题 ① 修改httpd.conf不起作用 ② 直接通过控制面板配置好像有延迟缓存

(done) 吴恩达版提示词工程 6. 转换 (翻译,通用翻译,语气风格变换,文本格式转换,拼写检查和语法检查)

视频&#xff1a;https://www.bilibili.com/video/BV1Z14y1Z7LJ/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 别人的笔记&#xff1a;https://zhuanlan.zhihu.com/p/626966526 6. 转换任务&#xff08;Transforming&#xff0…

什么是静态住宅ip,跨境电商为什么要用静态住宅ip

在数字时代&#xff0c;IP地址不仅是设备联网的“ID”&#xff0c;更是跨境电商运营中的关键工具。尤其对于需要长期稳定、安全操作的场景&#xff0c;静态住宅IP逐渐成为行业首选。 一、什么是静态住宅IP&#xff1f; 静态住宅IP&#xff08;Static Residential IP&#xff0…

Qemu-STM32(十七):STM32F103加入AFIO控制器

概述 本文主要描述了在Qemu平台中&#xff0c;如何添加STM32F103的AFIO控制器模拟代码&#xff0c;AFIO是属于GPIO引脚复用配置的功能。 参考资料 STM32F1XX TRM手册&#xff0c;手册编号&#xff1a;RM0008 添加步骤 1、在hw/arm/Kconfig文件中添加STM32F1XX_AFIO&#x…

QuecPython+audio:实现音频的录制与播放

概述 QuecPython 作为专为物联网设计的开发框架&#xff0c;通过高度封装的 Python 接口为嵌入式设备提供了完整的音频处理能力。本文主要介绍如何利用 QuecPython 快速实现音频功能的开发。 核心优势 极简开发&#xff1a;3行代码完成基础音频录制与播放。快速上手&#xf…

企业架构之旅(3):TOGAF ADM架构愿景的核心价值

一、引言&#xff1a;为什么架构愿景是企业架构的「导航图」 在企业数字化转型的浪潮中&#xff0c;TOGAF ADM&#xff08;架构开发方法&#xff09;作为公认的企业架构「方法论圣经」&#xff0c;其首个关键阶段 —— 架构愿景&#xff08;Architecture Vision&#xff09;&a…