news 2026/6/15 13:29:00

[特殊字符] 背包问题详解(0/1 背包、完全背包、多重背包)——附 C++ 实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[特殊字符] 背包问题详解(0/1 背包、完全背包、多重背包)——附 C++ 实现

🧳 背包问题详解(0/1 背包、完全背包、多重背包)——附 C++ 实现

一、什么是背包问题?

背包问题(Knapsack Problem)是经典的动态规划问题之一:

给定一个容量有限的背包和若干物品,每个物品有体积(或重量)*和*价值,问如何选择物品使得总价值最大**。

根据每个物品可选次数不同,背包问题主要分为:

  • 0/1 背包(每个物品最多选一次)
  • 完全背包(每个物品可以选无限次)
  • 多重背包(每个物品有固定数量)

二、0/1 背包问题

1️⃣ 问题描述

  • 背包容量:W
  • 物品数量:n
  • i个物品:
    • 重量:w[i]
    • 价值:v[i]
  • 每个物品最多选一次

目标:
👉 在不超过背包容量的前提下,使总价值最大。


2️⃣ 状态定义

令:

dp[j] = 容量为 j 时能获得的最大价值

3️⃣ 状态转移方程

对于第i个物品:

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

⚠️关键点
j必须从大到小遍历,防止一个物品被选多次。


4️⃣ C++ 实现(0/1 背包)

#include<bits/stdc++.h>usingnamespacestd;intmain(){intn,W;cin>>n>>W;vector<int>w(n),v(n);for(inti=0;i<n;i++){cin>>w[i]>>v[i];}vector<int>dp(W+1,0);for(inti=0;i<n;i++){for(intj=W;j>=w[i];j--){dp[j]=max(dp[j],dp[j-w[i]]+v[i]);}}cout<<dp[W]<<endl;return0;}

三、完全背包问题

1️⃣ 问题描述

与 0/1 背包类似,但:

每个物品可以选无限次


2️⃣ 状态转移区别

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

⚠️关键区别
j必须从小到大遍历,允许多次使用当前物品。


3️⃣ C++ 实现(完全背包)

#include<bits/stdc++.h>usingnamespacestd;intmain(){intn,W;cin>>n>>W;vector<int>w(n),v(n);for(inti=0;i<n;i++){cin>>w[i]>>v[i];}vector<int>dp(W+1,0);for(inti=0;i<n;i++){for(intj=w[i];j<=W;j++){dp[j]=max(dp[j],dp[j-w[i]]+v[i]);}}cout<<dp[W]<<endl;return0;}

四、多重背包问题

1️⃣ 问题描述

  • 每个物品最多只能选k[i]

2️⃣ 常见解决方法

✅ 方法一:暴力枚举(不推荐)

三重循环,时间复杂度高。

✅ 方法二:二进制拆分(推荐)

k个物品拆成:

1, 2, 4, ..., 剩余

然后转化为0/1 背包问题


3️⃣ C++ 实现(二进制优化)

#include<bits/stdc++.h>usingnamespacestd;intmain(){intn,W;cin>>n>>W;vector<int>dp(W+1,0);for(inti=0;i<n;i++){intw,v,k;cin>>w>>v>>k;for(intc=1;k>0;c<<=1){intnum=min(c,k);k-=num;intweight=num*w;intvalue=num*v;for(intj=W;j>=weight;j--){dp[j]=max(dp[j],dp[j-weight]+value);}}}cout<<dp[W]<<endl;return0;}

五、三种背包对比总结

类型每件物品j 遍历方向本质
0/1 背包最多 1 次从大到小防止重复选
完全背包无限次从小到大允许重复
多重背包有上限转化为 0/1二进制优化

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 1:07:14

背单词项目

1.v1&#xff08;第一版比较简陋&#xff0c;反正也是先实验&#xff09;:首先&#xff0c;创建随机对象和有获取功能的对象接着&#xff0c;创建字符串数组存入单词和相应的中文最后就是背单词软件的逻辑&#xff0c;先学习一下其中具体的方法&#xff1a;nextInt&#xff1a;…

作者头像 李华
网站建设 2026/6/15 11:47:12

15、UNIX内核基础与配置详解

UNIX内核基础与配置详解 1. 为何要了解UNIX内核 在日常系统管理工作中,如添加用户、运行作业、打印文件、执行备份恢复,甚至开关机等操作,似乎不需要深入了解UNIX内核。但实际上,如果从不添加硬件、不调整系统以提升性能,确实无需过多了解内核。然而,在多年的系统管理经…

作者头像 李华
网站建设 2026/6/12 20:39:16

基于改进YOLO13-C3k2-WDBB的石棉类型识别与检测系统详解

1. 基于改进YOLO13-C3k2-WDBB的石棉类型识别与检测系统详解 1.1. 系统概述 石棉作为一种常见的建筑材料&#xff0c;由于其优良的绝缘、防火和耐腐蚀性能&#xff0c;曾广泛应用于建筑、工业和船舶等领域。然而&#xff0c;石棉纤维被吸入人体后可能导致严重的健康问题&#…

作者头像 李华
网站建设 2026/6/12 5:40:30

用带头节点的链式存储实现栈的操作

1.栈是一种只能在一端进行插入和删除的线性表2.先构建一个数据类型&#xff0c;里面有next,data,top(可有可无&#xff09;typedef struct LNode {int top;//初始化的时候top等于-1&#xff0c;只有有数据就让top1,这个数据项可有可无struct LNode* next;//和单链表一样int dat…

作者头像 李华
网站建设 2026/6/15 12:38:08

java计算机毕业设计社区应急管理信息系统 智慧社区应急响应信息平台 城市基层突发事件数字化管理系统

计算机毕业设计社区应急管理信息系统2blhj9 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。进入信息时代&#xff0c;传统纸质或微信群接龙式的社区应急模式早已暴露出响应慢、信…

作者头像 李华
网站建设 2026/6/15 13:24:02

组合模式详解

什么是组合模式&#xff1f;组合模式(Composite Pattern)&#xff0c;是一种结构型设计模式&#xff0c;这种模式将对象组合成树形结构&#xff0c;以表示部分--整体的层次关系&#xff0c;组合模式使得用户对单个对象和组合对象的使用具有一致性。组合模式的结构角色说明Compo…

作者头像 李华