【算法设计与分析】7、0/1背包问题,动态规划

/**
* 书本:《算法分析与设计》
* 功能:给定n种物品和一个背包,物品i的重量是Wi, 其价值为Vi,问如何选择装入背包的物品,使得装入背包的物品的总价值最大?
* 文件:beiBao.cpp
* 时间:2014年11月30日19:22:47
* 作者:cutter_point
*/

#include <iostream>

#define SIZEBEIBAO 20

using namespace std;

//这个背包问题的最优的子结构是
/*
首先这里一共有m种物品,背包的总容量是W
1、从第n个开始往前面开始计算,初始化第n个
即c[n][j] j是背包的容量,从0开始递增到背包最大的容量w则当j >= w的时候吧第n个的价值加上去就是加上Vn
													   当0 <= j <  w的时候那么低n个不加上去那就是n
2、当考虑第i个的时候i < n,那么就分为
max{ c[i+1][j] , c[i+1][j-Wi]+Vi} 当j >= Wi
就是 m[i+1][j]
*/
//我们用m(i,j)表示为已经判断好了1:i-1的序列的背包最大价值,并且此时的背包剩余的容量为j,对物品i进行判断
//n是个数,w是背包最大容量,c[n, w]是背包在n个物品下背包大小是w的最优价值,v是每个的价值,wi是每个的重量
int beiBao(int n, int w, int c[SIZEBEIBAO][SIZEBEIBAO], int *v, int *wi)
{
	c[SIZEBEIBAO][SIZEBEIBAO] = { 0 };	//初始化所有的值
	//从第n个开始往前面开始计算,初始化第n个
	for (int i = 0; i <= w; ++i)	//容量重0到w的初始化
	{
		if (i >= wi[n])	//和第n个比较那个重量,只要超过了这个重量那么价值都是Vn
		{
			c[n][i] = v[n];
		}
		else
		{
			c[n][i] = 0;	//背包容量达不到,那么最优的价值只能是0
		}
	}

	//这里从第n个开始
	//物品从第n个往回迭代
	/*
	2、当考虑第i个的时候i < n,那么就分为
	max{ c[i+1][j] , c[i+1][j-Wi]+Vi}
	当j >= Wi  c[i+1][j-Wi]+Vi
	否则就是 m[i+1][j]
	*/
	for (int i = n-1; i >= 0; --i)
	{
		for (int j = 0; j <= w; ++j)	//背包容量从小增加到最大
		{
			if (j >= wi[i])	//当重量达到了这个要求的时候
				c[i][j] = c[i + 1][j - wi[i]] + v[i];	//第i个物品加入背包的时候得到的价值
			else
				c[i][j] = c[i + 1][j];	//当第i个不加如背包的时候
		}
	}

	//最终的最优解就是
	return c[1][w];

	/*
	//当物品的数量从1到n的时候
	for (int i = 1; i <= n; ++i)
	{
		c[i][0] = 0;	//对应的0容量的背包的价值最优肯定是0
		//不同的重量就会有不同的背包最优价值
		for (int wx = 1; wx <= w; ++wx)
		{
			//当对应的重量在增加的时候
			//这里要判断这个重量是否比背包可以装的容量大,这里物品的数量i的时候
			if (wi[i] > wx)
				c[i][wx] = c[i - 1][wx];	//2、当Wi > W的时候,第i个的总量>总重量的时候 c[n, w]=c[n-1, w]
			else //3、当n > 0且 Wi <= w的时候 c[n, w]=MAX{ c[n-1, w], c[n-1, w-Wi]+vi }
			{
				//比较这两个中最大的那个
				int temp = c[i - 1][wx - wi[i]] + v[i];

				if (c[i - 1][wx] > temp)
					c[i][wx] = c[i - 1][wx];
				else
					c[i][wx] = temp;
			}
		}
	}
	*/
}

//得到背包问题的向量解
void qiux(int c[SIZEBEIBAO][SIZEBEIBAO], int *x, int *wi, int w, int n)
{
	for (int i = 1; i < n; ++i)	//从一个物品到 n个物品
	{
		if (c[i][w] == c[i + 1][w])
			x[i] = 0;	//如果加了下一个物品但是最优值没变,说明前面那个没有加入到里面
		else
		{
			x[i] = 1;	//如果加了一个物品价值变了,那么说明这个新的物品可以添加到背包里面去
			//加入后占用了质量
			w -= wi[i];
		}
	}

	//最后一个物品是否装入看c[n][w]的最后剩余的w是否还够装,由于最后一个c[i][w] == c[i + 1][w]无法判断
	x[n] = (c[n][w]) ? 1 : 0;
}

int main()
{
	int wi[4] = {0, 4, 3, 2};
	int v[4] = { 0, 5, 2, 1 };
	int n = 3, w = 6;
	int c[SIZEBEIBAO][SIZEBEIBAO] = { 0 };
	int x[SIZEBEIBAO] = { 0 };

	cout << "求得最优的价值是:" << endl;
	cout << beiBao(n, w, c, v, wi);

	cout << "则向量x是:" << endl;
	qiux(c, x, wi, w, n);
	for (int i = 1; i <= n; ++i)
		cout << x[i] << " ";
	cout << endl;

	return 0;
}

时间: 2024-12-09 19:27:37

【算法设计与分析】7、0/1背包问题,动态规划的相关文章

【算法设计与分析基础】20、动态规划-硬币搜集问题

题目: 在n*m格木板中放有一些硬币,每格的硬币数目最多为一个.在木板左上方的一个机器人需要搜集尽可能多的硬币并把他们带到右下方的单元格,每一步,机器人可以从当前的位置向右移动一格 或者向下移动一格,当机器人遇到一个有硬币的单元格的时,就会将这枚硬币搜集起来 解题: 硬币收集的时候,我们 从结果状态开始看,当搜集当前硬币的时候,只有两种方式,从上往下搜集,或者从左向右搜集 也就是当前f[i,j] = max{f[i, j - 1], f[i - 1, j]},初始化第一行和第一列,从第二行和列开

算法设计与分析——回溯法算法模板

以深度优先方式系统搜索问题解的算法称为回溯法.在回溯法中,解空间树主要分为了四种子集树.排列树.n叉树和不确定树. 在<算法设计与分析课本>中介绍了11个回溯法的问题样例,这里根据解空间树的类型做一个分类. 子集树 装载问题 符号三角形问题 0-1背包问题 最大团问题 算法模板: void backtrack(int t) { if(搜索到叶子结点) { return; } for(i=0; i<=1; i++) //01二叉树 { if(满足约束函数和限界函数)//剪枝 { backt

(转)常用的算法设计与分析-一夜星辰的博客

算法设计与分析 分治法 思想 1. 将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同.递归地解这些子问题,然后将各子问题的解合并得到原问题的解. 2. divide-and-conquer(P) { if(|P| <= n0)adhoc(P); divide P into samller subinstances P1,P2...,Pk; for(int i = 1;i < k;i++) { yi = divide-and-conquer(Pi); } retu

算法设计与分析 ------最近对问题与8枚硬币问题

利用减治法实现8枚硬币问题: 参考资料:http://blog.csdn.net/wwj_748/article/details/8863503    算法设计--八枚硬币问题 1 #include "stdafx.h" 2 #include <iostream> 3 #include <stdio.h> 4 using namespace std; 5 6 7 void eightcoin(int arr[]); 8 void compare(int a,in

《计算机算法设计与分析》v4 第1章 算法概述 算法实现题答案

博主今年刚上大三,正好开算法这门课.由于博主本人比较喜欢算法但又比较懒,啃不动算法导论,所以决定拿这本书下手. 这本书是王晓东的第四版<计算机算法设计与分析>.初步打算将每章后面的算法题都用代码实现. 有些题跟某个ACM题目很像,我会把该ACM题的链接贴上.有的题没OJ交所以可能是错的.如有发现,还望指出. 1-1 统计数字问题 http://poj.org/problem?id=2282 这个题要按位分解,一位一位的来处理. #include<iostream> #include

算法设计与分析(屈婉玲)pdf

下载地址:网盘下载 算法设计与分析本教材为计算机科学技术专业核心课程"算法设计与分析"教材.<算法设计与分析>以算法设计技术和分析方法为主线来组织各知识单元,主要内容包括基础知识.分治策略.动态规划.贪心法.回溯与分支限界.算法分析与问题的计算复杂度.NP完全性.近似算法.随机算法.处理难解问题的策略等.书中突出对问题本身的分析和求解方法的阐述,从问题建模.算法设计与分析.改进措施等方面给出适当的建议,同时也简要介绍了计算复杂性理论的核心内容和处理难解问题的一些新技术. &

算法设计与分析-Week12

题目描述 You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the c

【通知】《算法设计与分析》实验课、理论课补课、考试时间、加分等安排 及 个人目标设定

Logistic回归为概率型非线性回归模型,是研究二分类观察结果与一些影响因素之间关系的一种多 变量分析方法.通常的问题是,研究某些因素条件下某个结果是否发生,比如医学中根据病人的一些症状来判断它是 否患有某种病. 在讲解Logistic回归理论之前,我们先从LR分类器说起.LR分类器,即Logistic Regression Classifier. 在分类情形下,经过学习后的LR分类器是一组权值,当测试样本的数据输入时,这组权值与测试数据按 照线性加和得到 这里是每个样本的个特征. 之后按照s

算法设计与分析基础(第3版)读书笔记(及几处翻译上的错误~~)

算法设计与分析基础(第3版) p16 in-place翻译为'在位'?'就地'更合适点 p38 amortized应翻译为'均摊','摊销'这个词简直莫名其妙(可能因为翻译是做算法交易导致的?) p64 迭代优于递归(迭代始终是增量式的,而递归就没办法增量了,除非能够dump整个运行时栈) p73 通过算法可视化得到一个更好的非递归算法(人的图像认知直觉思维?) p79 验证一个拓扑是环.星.还是团?(这个地方有点意思,因为我想到了动态的Verify) p87 凸包问题:从数据结构上讲,Set<

算法设计与分析 - 李春葆 - 第二版 - pdf-&gt;word v3

1 1.1 第1章─概论 2 3 1.1.1 练习题 4 1. 下列关于算法的说法中正确的有( ). 5 Ⅰ.求解某一类问题的算法是唯一的 6 Ⅱ.算法必须在有限步操作之后停止 7 Ⅲ.算法的每一步操作必须是明确的,不能有歧义或含义模糊 8 Ⅳ.算法执行后一定产生确定的结果 9 A. 1个 B.2个 C.3个 D.4个 10 2. T(n)表示当输入规模为n时的算法效率,以下算法效率最优的是( ). 11 A.T(n)= T(n-1)+1,T(1)=1 B.T(n)= 2n2 12 C.T(n)