当前位置: 首页 > news >正文

【回溯法】0-1背包问题 C/C++(附代码)

0-1背包问题的回溯法解决

在这篇文章中已经讨论过0-1背包问题背包问题动态规划以及贪心解法,本文将介绍0-1背包问题的回溯法解决

问题描述

给定n种物品和一个容量为C的背包。物品i的重量是wi,其价值为vi。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?

问题分析

0-1背包问题是一个经典的组合优化问题,属于NP完全问题。它可以通过回溯法来解决,回溯法是一种系统地搜索问题解的方法。在回溯法中,我们通过构建解空间树来探索所有可能的解,并通过剪枝策略来减少搜索空间。

子集树

在回溯法中,0-1背包问题可以被看作是一个子集树问题。每个节点代表一个决策点,即是否将当前物品放入背包中。左子树表示将当前物品放入背包,右子树表示不放入背包。
在这里插入图片描述

剪枝条件

为了减少搜索空间,我们可以使用以下剪枝条件:

  1. 进入左子树的条件:当前物品的重量不超过背包的剩余容量,即 w[i] + cw <= c
  2. 进入右子树的条件:剩余物品的总价值加上当前已放入背包的物品价值之和不小于已有的最大价值,即 r + cv >= best

(这个问题和装载问题不能说很像吧,起码也是一模一样,代码相似度99%,剩下的1%别忘了背包问题有重量和价值两个量)

代码实现

数据结构

  • best:记录当前找到的最大价值。
  • bestx[]:记录最优解,即哪些物品被放入背包。
  • x[]:记录当前解,即当前路径上哪些物品被放入背包。
  • cw:当前背包中物品的总重量。
  • cv:当前背包中物品的总价值。
  • r:记录剩余物品的总价值,初始值为所有物品的总价值。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#define MAX 100int n; // 物品数量
int w[MAX]; // 物品重量
int v[MAX]; // 物品价值
int c; // 背包容量
int best = 0; // 最大价值
int bestx[MAX]; // 记录最优解
int x[MAX]; // 当前解
int cw = 0; // 当前重量
int cv = 0; // 当前价值
int r = 0; // 剩余物品的总价值void backtrack(int i) {if (i > n) {best = cv;for (int j = 1; j <= n; j++) {bestx[j] = x[j];}return;}r -= v[i];if (w[i] + cw <= c) { // 进入左子树cw += w[i];cv += v[i];x[i] = 1;backtrack(i + 1);cw -= w[i];cv -= v[i];x[i] = 0;}if (r + cv >= best) { // 进入右子树x[i] = 0;backtrack(i + 1);}r += v[i];
}int main() {cin >> n >> c;for (int i = 1; i <= n; i++) {cin >> w[i] >> v[i];r += v[i];}backtrack(1);cout << "最大价值:" << best << endl;for (int i = 1; i <= n; i++)cout << bestx[i] << " ";return 0;
}

代码说明

  • 进入下一层结点:在进入下一层结点时,需要将 r 减去当前物品的价值,因为不论这个物品是否放入背包,r 是剩余物品的总价值,都不应该包含当前物品。
  • 退回上一层结点:在退回上一层结点时,需要将 r 加回当前物品的价值。
  • 剪枝条件:在进入右子树时,已经判断过走右支也可以获得最优解,因此不需要额外判断是否 cw >= bestw

实例

假设有5件物品,背包容量为10,输入如下:

物品重量 (w)价值 (v)
126
223
365
454
546

运行程序后,输出最大价值为15,放入背包的物品为第1、2、5件物品。经验证,该解正确。

在这里插入图片描述

http://www.xdnf.cn/news/540451.html

相关文章:

  • 【C++模板与泛型编程】实例化
  • lovart design 设计类agent的系统提示词解读
  • python调用pip模块,使用pip_install脚本,在IDE中运行自动记录安装包到requirements文件的代码示例
  • Mergekit——任务向量合并算法Ties解析
  • 从基础到高级:网站反爬技术全景解析与第三方工具对比
  • C++类与对象--3 C++对象模型和this指针
  • 【计网】作业5
  • Python 训练营打卡 Day 29
  • 物流项目第二期(用户端登录与双token三验证)
  • python学习day1
  • C++字符串处理:`std::string`和`std::string_view`的区别与使用
  • 设计一个程序,将所有的小写字母转换为大写字母
  • 打造灵感投掷器:我的「IdeaDice」开发记录
  • sqli-labs第九关—‘时间盲注
  • 虚拟机的三个核心类加载器
  • 注解(Annotation)概述
  • web应用技术第5次课-springboot入门
  • 中科固源Wisdom平台发现NASA核心飞行控制系统(cFS)通信协议健壮性缺陷!
  • 九、异形窗口
  • 有关Groutine无限创建的分析
  • YOLO模型使用jupyterlab的方式进行预测/推理(示例)
  • Linux配置SSH密钥认证
  • 程序化 SEO 全攻略:如何高效提升网站排名?
  • 【python】返回所有匹配项的第一个元素、第二个元素。。。
  • 龙芯中科2024年度业绩说明会:企稳向好,布局未来!
  • 贵州某建筑物挡墙自动化监测
  • Dolphinscheduler执行工作流失败,后台报duplicate key错误
  • 如何通过生成式人工智能认证(GAI认证)提升自己的技能水平?
  • C++经典库介绍
  • PH热榜 | 2025-05-18