算法设计与分析——回溯法——01背包问题

回溯法——0-1背包问题 问题描述给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问:应如何选择装入背包的物品,使得装入背包中物品的总价值最大?算法设计分析从所有的物品中选取若干将它们装进背包,在满足限制条件的情况下,获得最大的收益。既然要选择一个对象的子集,解空间就应该组织成子集树结构。要设计的递归算法使用深度优先搜索子集树:​ 对于左孩子,满足限制条件即可;对于右孩子,需要利用界定函数计算此节 阅读详情

//0-1背包问题 回溯法求解
#include<bits/stdc++.h>
#include <iostream>

using namespace std; 

template<class Typew,class Typep>
class Knap
{
	public:
		Typep Bound(int i);
		void Backtrack(int i);
	
		Typew c;	//背包容量
		int n;		//物品数
		Typew *w;	//物品重量数组
		Typep *p;	//物品价值数组
		Typew cw;	//当前重量
		Typep cp;	//当前价值
		Typep bestp;//当前最后价值

};

template<class Typew,class Typep>

Typep Knapsack(Typep p[],Typew w[],Typew c,int n);

template <class Type>

inline void Swap(Type &a,Type &b);

template<class Type>

void BubbleSort(Type a[],int n);
int main()
{
	int n;

	int c = 7;//背包容量	
	cout<<"请输入物品数目:";	//物品数
	cin>>n;
	int p[n+1];// p[] = {0,9,10,7,4};//物品价值 下标从1开始
		p[0]=0;
	int w[n+1];//int w[] = {0,3,5,2,1};//物品重量 下标从1开始
		w[0]=0;
 	cout<<"输入物品的价值序列:";
	for(int i=1;i<=n;i++)
	{
		cin>>p[i];
	} 
	cout<<"输入物品的重量序列:";
	for(int i=1;i<=n;i++)
	{
		cin>>w[i];
	}

	cout<<"背包容量为:"<<c<<endl;
	cout<<"物品重量和价值分别为:"<<endl;
	for(int i=1; i<=n; i++)
	{
		cout<<"("<<w[i]<<","<<p[i]<<") ";
	}
	cout<<endl;
	cout<<"背包能装下的最大价值为:"<<Knapsack(p,w,c,n)<<endl;
	return 0;
}
template<class Typew,class Typep>
void Knap<Typew,Typep>::Backtrack(int i)
{
	if(i>n)//到达叶子节点
	{
		bestp = cp;
		return;
	}
	if(cw + w[i] <= c)//进入左子树
	{
		cw += w[i];
		cp += p[i];
		Backtrack(i+1);
		cw -= w[i];
		cp -= p[i];
	}
	if(Bound(i+1)>bestp)//进入右子树
	{
		Backtrack(i+1);
	}
}
template<class Typew, class Typep>
Typep Knap<Typew, Typep>::Bound(int i)// 计算上界
{
	Typew cleft = c - cw;  // 剩余容量
	Typep b = cp;
	// 以物品单位重量价值递减序装入物品
	while (i <= n && w[i] <= cleft) 
	{
		cleft -= w[i];
		b += p[i];
		i++;
	}
   // 装满背包
   if (i <= n)
   {
	   b += p[i]/w[i] * cleft;
   }
   return b;
}
class Object
{
	template<class Typew,class Typep>
	friend Typep Knapsack(Typep[],Typew [],Typew,int);
	public:
		int operator <= (Object a)const
		{
			return (d>=a.d);
		}
	private:
		int ID;
		float d;	
};
template<class Typew,class Typep>
Typep Knapsack(Typep p[],Typew w[],Typew c,int n)
{
	//为Knap::Backtrack初始化
	Typew W = 0;
	Typep P = 0;
	Object *Q = new Object[n];
	for(int i=1; i<=n; i++) 
	{
		Q[i-1].ID = i;
		Q[i-1].d = 1.0 * p[i]/w[i];
		P += p[i];
		W += w[i];
	}
	if(W <= c)//装入所有物品
	{
		return P;
	}

	//依物品单位重量价值排序

	BubbleSort(Q,n);
	Knap<Typew,Typep> K;
	K.p = new Typep[n+1];
	K.w = new Typew[n+1];
	for(int i=1; i<=n; i++)
	{
		K.p[i] = p[Q[i-1].ID];
		K.w[i] = w[Q[i-1].ID];
	}
	K.cp = 0;
	K.cw = 0;
	K.c = c;
	K.n = n;
	K.bestp = 0;
	//回溯搜索
	K.Backtrack(1);
	delete []Q;
	delete []K.w;
	delete []K.p;
	return K.bestp;
}

template<class Type>
void BubbleSort(Type a[],int n)
{
	 //记录一次遍历中是否有元素的交换   
     bool exchange;  
	 for(int i=0; i<n-1;i++)  
	 {  
		exchange = false ;  
		for(int j=i+1; j<=n-1; j++)  
		{  
			if(a[j]<=a[j-1])  
			{  
				Swap(a[j],a[j-1]); 
				exchange = true;  
			}   
		}   
		//如果这次遍历没有元素的交换,那么排序结束   
		if(false == exchange)  
		{
			 break ;  
		}
	 }
}
template <class Type>
inline void Swap(Type &a,Type &b)
{
	Type temp = a;
	a = b;
	b = temp;
}

在这里插入图片描述
贪心算法解决背包问题的主要时间用在了将其各种物品按其单位重量的价值从小到大排序 O(n*logn)

C/C++ 回溯法 解决0-1背包问题 代码 使用回溯法解决0-1背包问题,物品的(体积:价值)分别为(16:45),(15:25),(15:25)。背包的容量为30,要求:将3个物品装入背包使其得到的价值最大。 阅读详情

相关推荐

算法回溯法-0-1背包c++

// 回溯法0-1背包.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // ////思路差异: // 解为子集树:<=c,可进入左子集;>maxvule,则可以进入由结点 // // //// #include <iostream> #include <algorithm> using namespace std; class Knap { public: void Backtrack(int i); int bound(int i); int c,

weixin_52034824的博客 1196

回溯法解01背包问题(最通俗易懂,附C++代码)

问题描述: 01背包问题是算法中的经典问题,问题描述如下: 对于给定的N个物品,第i个物品的重量为Wi,价值为Vi,对于一个最多能装重量C的背包,应该如何选择放入包中的物品,使得包中物品的总价值最大? 回溯法简介: 回溯法的本质其实就是一种蛮力法,只是通过一定的方法可以使得蛮力法中的一些基本情况可以提前排除从而提高蛮力算法效率,回溯可以理解为排除这些不满足条件的基本情况的过程。 回溯法求解0-1背包问题的过程: 由于直接描述过程比较抽象,因此直接上例题 例题:假设N=3(有三件物品),三个物品的重量为{20

hanmo22357的博客 4万+

**[回溯法]**解决01背包问题

**[回溯法]**解决01背包问题 1.问题分析 01背包属于找最优解问题,用回溯法需要构造解的子集树。对于每一个物品i,对于该物品只有选与不选2个决策,总共有n个物品,可以顺序依次考虑每个物品,这样就形成了一棵解空间树: 基本思想就是遍历这棵树,以枚举所有情况,最后进行判断,如果重量不超过背包容量,且价值最大的话,该方案就是最后的答案。 在搜索状态空间树时,只要左子节点是可一个可行结点,搜索就进入其左子树。对于右子树时,先计算上界函数,以判断是否将其减去(剪枝)。 2.问题的解决方案 利用回溯法试设计一个

qq_52979639的博客 534

回溯法解决0/1背包问题(c++)

0-1背包(回溯法) 题目内容 用回溯法解决0-1背包问题时,其解空间有长度为n的0-1向量组成,并可以组织成高度为n+1满二叉树。二叉树的结点按层次遍历的顺序从上到下、从左到右的顺序编号(从1开始)。 采用回溯法解决问题时,可以使用约束条件对左子树进行剪枝,使用限界条件对右子树进行剪枝。 在本题中,约束条件为tw+w[i]<=C,限界条件为tv+rv[i]>maxv 输入要求 有多组数据。 每组数据包含三行。 第一行包含两个整数C(1 <= C <= 10000)和n(1 <

weixin_45656365的博客 2687

东北大学算法分析与设计实验全解析:Java代码实现与报告

格雷码的本质是一种排列方式,旨在对 $ 0 $ 到 $ 2^n - 1 $ 的整数进行重新排序,使得每一对连续数值之间的汉明距离为 1。该编码最早由贝尔实验室的 Frank Gray 提出,用于减少模拟信号数字化过程中的误差。现代计算机科学将其抽象为一种组合数学对象,广泛应用于枚举、回溯搜索和超立方体网络拓扑等领域。最优子结构是指一个问题的最优解可以由其子问题的最优解构造而成。

weixin_42593549的博客 868

保姆级教程:用xmir-patcher一键解锁Redmi AX3000路由器的SSH(附视频演示)

本文提供Redmi AX3000路由器SSH解锁的保姆级教程,详细介绍了使用xmir-patcher工具一键解锁SSH的步骤,包括环境搭建、工具获取、图形化操作详解及常见问题排查。解锁后,用户可通过SSH连接实现刷机、插件安装、网络优化等高级功能,提升路由器性能。

weixin_29216049的博客 729

算法设计与分析实验四:利用回溯法求解01背包问题和TSP问题

(1)利用回溯法编程求解0-1背包问题,并对算法进行时间复杂性分析; (2)利用回溯法编程求解TSP问题,并对算法进行时间复杂性分析。

qq_61996033的博客 2427

virtuoso--DFF

27-实验课-std_cell2

qq_61440044的博客 2004

基于回溯法和分支限界法求解01背包问题

基于回溯法和分支限界法求解01背包问题 问题描述 现有n个物品,1个背包。对物品i,其价值为viv_ivi​ ,重量为WiW_iWi​,背包的容量为WWW,如何选取物品使得背包里转入物品的总价值最大? 在约束条件为:选取物品的重量小于等于背包重量的情况下,尽可能让背包中物品的总价值最大。 算法设计 01背包问题是自己选取问题,该问题的解空间可用子集树表明。设currentTotalValue是当前已经装入背包的物品的总价值、residueValue是剩余的未知是否装入物品的总价值,也就是未被搜索到物品的总价

lhd1110的博客 4310

Unity游戏开发实战:用柏林噪声打造3D随机地形(附完整C#代码)

本文详细介绍了如何在Unity游戏开发中使用柏林噪声算法生成3D随机地形,包含完整的C#代码实现。从基础柏林噪声原理到高级参数控制,再到性能优化和常见问题解决,帮助开发者掌握程序化地形生成技术,打造丰富多变的游戏世界。

weixin_29281941的博客 99

Qt应用软件【协议篇】自定义协议处理串口半包贴包

Qt串口数据,半包,贴包,丢包数据处理

小鱼酱的博客 1211

回溯法求0/1背包问题

回溯法求解0/1背包问题

m0_68563008的博客 1137

mapbox进阶,dem数据转为等高面,加载转换后的等高面到地图

本文详细介绍如何基于mapbox-gl v3.*.* 版本,使用dem数据转为等高面,加载转换后的等高面到地图,亲测可用。希望能帮助到您。一起学习,加油!加油!

我哎GIS博客 407

回溯法采用的搜索策略_算法设计:回溯法-解决01背包问题

一、算法思想 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。有时会遇到这样一类题目,它的问题可以分解,但是又不能得出明确的动态规划或是递归解法,此时可以考虑用回溯法解决此类问题。回溯法的优点 再于其程序结构明确,可读性强,易于理解,而且通过对问题的分析...

weixin_35050881的博客 2312

Cesium雷达追踪追踪(圆锥体效果)

【代码】Cesium雷达追踪追踪(圆锥体效果)

God's asylum的博客 2931

Android16 RK3576 Bluetooth source和sink模式切换

摘要:本文介绍了在RK3576平台上实现蓝牙A2DP模式动态切换的修改方案。通过在device配置文件中添加A2DP Sink相关属性,修改Bluetooth模块代码实现:1)在Config.java中增加persist.bluetooth.rka2dpsink属性控制模式切换;2)修改A2dpSinkStreamHandler.java取消音频焦点限制;3)调整btif_a2dp_sink.cc默认授予音频焦点。最终通过设置persist.bluetooth.rka2dpsink属性为true/false

tzj1058756809的博客 860

o-1背包问题迭代_算法设计:回溯法-解决01背包问题

一、算法思想 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。有时会遇到这样一类题目,它的问题可以分解,但是又不能得出明确的动态规划或是递归解法,此时可以考虑用回溯法解决此类问题。回溯法的优点 再于其程序结构明确,可读性强,易于理解,而且通过对问题的分析...

weixin_39524984的博客 5644

SAP CDS View 教程里的标准视图:SEPM_I_SalesOrderItem_E 当成一张表来用之前,你需要先弄清它到底是什么

摘要:SEPM_I_SalesOrderItem_E 是 SAP EPM demo 中的预交付 CDS 视图,用于表示销售订单行项目数据。它采用 VDM 命名规范,_E 后缀表示对外隐藏内部 UUID 键,提供业务友好的外部 ID 接口。该视图常见于 ABAP Platform 7.50+、开发版系统及 Gateway 教程中,可像表一样通过 Open SQL 查询。实际项目中,这类视图能有效解决内外系统键值映射问题,示例代码展示了如何查询其数据。使用时需注意系统是否安装了 EPM demo 内容。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 547

【回溯法】--01背包问题

转载自:https://blog.youkuaiyun.com/qian2213762498/article/details/79420269 【回溯法】--01背包问题 1、问题描述   给定n种物品和一背包。物品i的重量是wi>0,其价值为vi>0,背包的容量为c。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? (要求使用回溯法)  例如: 2、算法分析 【整体...

isanth 1739

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

算法与设计分析期末复习

算法与设计分析期末复习 1.背包问题 算法思想:贪心法 (1)数据结构及初始化。将n种宝物的重量和价值存储在结构体three(包含重量、价值、性价比三个成员)中,同时求出每种宝物的性价比也存储在对应的结构体three中,将其按照性价比从高到底排列。采用sum来存储背包存储的最大价值,初始化为0. (2)根据贪心策略,按照性价比从大到小选取宝物,直到背包存储能力。每次选取性价比高的宝物,判断是否小于...

qq_42699988的博客 890

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

算法设计与分析总结

一、 算法分析 1.1 去年试卷 1.1.1 填空题 1.1.1.1 最长公共子序列算法采用的是动态规划 1.1.1.2 在对问题的解空间树进行搜索的方法中,一个活节点最多有一次机会成为或节点的是分支限界法。 1.1.1.3 实现最大子段和利用的算法是动态规划法 1.1.1.4 广度优先是分支界限法的一种搜索方式 1.1.1.5 衡量一个算法的好坏标准是时间复杂度低 1.1.1.6 Strasse...

赛博夫子 2000

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

算法设计与分析复习

1.动态规划 主要步骤: 1.找出最优解的性质,以刻画其结构特征 2.递归地定义最优值 3.自底向上计算最优值 4.构造最优解 1.0 动态规划算法的基本要素为:最优子结构和重叠子问题性质 1.1 不是动态规划算法基本步骤的是:找出最优解的解空间 1.2 动态规划法是自底向上,贪心算法自顶向下 1.3 备忘录方法是动态规划算法的变形 1.4 最长公共子序列算法利用的算法是动态规划法 1.5矩阵连乘问题的算法可由动态规划算法设计实现 1.6 动态规划解决01背包问题不需要排序 1.7 最大子段和算法 i

weixin_44658053的博客 2703

中国矿业大学2021年12月算法导论课程试卷回忆版

中国矿业大学2021年12月算法导论课程试卷回忆版

weixin_45628777的博客 2908

回溯法求解01背包问题

解决01背包问题的方法有:动态规划法,回溯法,分治界限法  知识储备:01背包问题与背包问题的区别;回溯法的基本思想;最优值与最优解的含义 参考书籍:王晓东《算法设计与分析》 //回溯法求解01背包问题 #include   using namespace std;      class Knap   {   public:       Knap(double *pp,do

马小橙的专栏 4390

回溯法解决八皇后和0,1背包问题和排列问题

回溯法其实就是一种穷举算法 八皇后问题的代码: public class EightQueuen { int count = 0; public boolean place(int[] array,int col){ boolean ret = false; if(col == 8){ for(int i = 0; i < array.length; i++){

fenglvming的专栏 879

算法分析与设计:0-1背包问题(回溯法)【本文算法的时空复杂度都未达到最优,核心目的在于展现并理解回溯法的算法过程】

===== 本文算法的时空复杂度都未达到最优,核心目的在于展现并理解回溯法的算法过程。===== 0-1背包问题 给定 nnn 种物品和一个背包。物品 iii 的重量为 wiw_iwi​,其价值为 pip_ipi​,背包的容积为 ccc。问如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 回溯法 回溯法是最常用的解题方法,有“通用的解题法”之称。当要解决的问题有若干可行解时,则可以在包含问题所有解的空间树中,按深度优先的策略,从根节点出发搜索解空间树。算法搜索至解空间树的任一结点时,总是先判断

SongXJ的博客 913
上一篇: 算法设计与分析——动态规划——最大字段和问题
下一篇: 算法设计与分析——分支限界法——n皇后问题
943802606
博客等级 码龄6年 1万+粉丝 177原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值