news 2026/7/24 12:03:50

[特殊字符] 背包问题详解(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/7/21 13:30:40

2、UNIX基础入门教程

UNIX基础入门教程 1. UNIX系统概述 UNIX是一个多用户、多任务的操作系统环境,与个人计算机不同,它天生就允许多个用户同时访问系统。无论你是在大型多用户系统上使用UNIX,还是使用基于UNIX的专用工作站,其多用户、多任务的架构都会影响你的工作方式以及系统对你作为用户和…

作者头像 李华
网站建设 2026/7/21 18:40:18

6、互联网通信全解析:从邮件到多媒体的多元世界

互联网通信全解析:从邮件到多媒体的多元世界 1. 互联网通信概述 互联网自诞生以来,其核心目的便是促进人们之间的交流。最初由军方开发,旨在构建一个在核攻击下仍能持续运行的分布式通信网络。随着时间的推移,互联网已广泛惠及众多群体,如中学、家庭用户和私营企业等。在…

作者头像 李华
网站建设 2026/7/24 8:16:22

vue基于Spring Boot框架 农产品销售供应商管理系统_m11i2507_

目录具体实现截图项目介绍论文大纲核心代码部分展示项目运行指导结论源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作具体实现截图 本系统&#xff08;程序源码数据库调试部署讲解&#xff09;同时还支持java、ThinkPHP、Node.js、Spring B…

作者头像 李华
网站建设 2026/7/23 19:52:12

10、UNIX系统管理:技术与实践指南

UNIX系统管理:技术与实践指南 1. 系统管理概述 系统管理涵盖计算机系统的规划、安装和维护。随着计算机在商业中日益普及,系统管理成为众多组织的关键岗位。管理员不仅要掌握技术,还需具备规划、组织和人际沟通等非技术能力。例如,企业将越来越多的业务流程计算机化,如库…

作者头像 李华
网站建设 2026/7/23 23:45:17

vue基于SpringBoot的健身房管理系统设计与实现_45vy0km9_

目录 具体实现截图项目介绍论文大纲核心代码部分展示项目运行指导结论源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 具体实现截图 本系统&#xff08;程序源码数据库调试部署讲解&#xff09;同时还支持java、ThinkPHP、Node.js、Spring…

作者头像 李华
网站建设 2026/7/23 6:04:25

父子进程关系与终止机制详解

父子进程关系与终止机制 父子进程关系 子进程通过fork()系统调用创建&#xff0c;是父进程的副本。现代Linux内核&#xff08;如Ubuntu 18的Linux 5.4&#xff09;采用写时复制&#xff08;Copy-On-Write, COW&#xff09;技术&#xff1a;子进程初始共享父进程的内存空间&…

作者头像 李华