本解法的价值矩阵生成由上到下,行表示不同的物品编号,第i行表示有i-1种物品;列表示重量限制。r[i][j]表示仅有i-1号物品时,重量限制为j时,可以得到的最大价值。

价值矩阵r[i][j],i是物品的编号,j是背包的重量限制;物品编号矩阵p[i][j],表示达到价值r[i][j]时,背包里的物品最大编号。可以通过p[i][j] - p[i][ j - w[i - 1]]得到除去该最大编号物品后,物品第二大的编号,以此类推得到全部物品的清单。

r的生成是从上到下的,r[i][j] = max( r[i - 1][j], r[i][j - w[i - 1]] + v[i - 1] )。前一个是不加入节点i,则价值与只有i-1个节点,重量限制为j的价值相同。后一个是加入一个节点i,则价值为本行去除节点i的重量后,重量限制j-w[i]对应的价值,加上节点i能带来的价值v[i-1]。

下方大篇幅为完全背包代码。

若0-1背包有以下区别。

区别1 初始化时:

r[1][i] = i / w[0] * v[0];  --->   if(i<w[0]) r[1][i] = 0; else r[1][i] = v[0];
区别2 决定是否加入物品i时:

if(r[i - 1][j] > v[i - 1] + r[i][j - w[i - 1]]) ---> 
<pre name="code" class="cpp">if(r[i - 1][j] > v[i - 1] + r[i - 1][j - w[i - 1]])


#include <iostream>
#include <memory.h>
using namespace std;

int main(){
	int v[] = {1, 3, 5, 9};
	int w[] = {2, 3, 4, 7};
	int b = 10;
	int n = sizeof(v) / sizeof(v[0]);
	int **p = new int* [n + 1];//记录达到当前价值时装入的物品的最大编号,用于确定最后需要如何装入物品来达到最大价值
	int **r = new int* [n + 1];//记录动态规划的最大价值
	int i, j;
	for(i = 0; i < n + 1; i++){//创建二维矩阵,并初始化第一列的值为1
		r[i] = new int [b + 1];
		p[i] = new int [b + 1];
		r[i][0] = 0;
		p[i][0] = 0;
	}
	for(i = 0; i < b + 1; i++){//只装入第一件物品,作为动态规划的起始值
		r[0][i] = 0;
		r[1][i] = i / w[0] * v[0];
		p[0][i] = 0;
		if(r[1][i]){//不为0,说明装入了第一件物品
			p[1][i] = 1;	
		}
		else{
			p[1][i] = 0;
		}
	}
	for(i = 2; i < n + 1; i++){
		for(j = 1; j < b + 1; j++){
			if(w[i - 1] > j){//当前物品装不进去
				r[i][j] = r[i - 1][j];
				p[i][j] = p[i - 1][j];
			}
			else{//能装入当前物品,比较装入该物品(该物品价值 + 去掉该物品重量后,剩余重量所能达到的最大价值)和不装入该物品哪种情况价值更高,选择高的那个
				if(r[i - 1][j] > v[i - 1] + r[i][j - w[i - 1]]){//不装入当前物品
					r[i][j] = r[i - 1][j];
					p[i][j] = p[i - 1][j];
				}
				else{//装入当前物品
					r[i][j] = v[i - 1] + r[i][j - w[i - 1]];
					p[i][j] = i;
				}
			}
		}
	}
	int *o = new int [n];//记录达到最大价值时装入的每一件物品的数量
	memset(o, 0, n * sizeof(int));
	i = b;//当前背包重量
	while(i > 0){
		j = p[n][i];
		if(j > 0){
			o[j - 1]++;
			i -= w[j - 1];
		}
		else{
			break;
		}
	}
	cout<<"最大价值:"<<r[n][b]<<endl;
	for(i = 0; i < n; i++){
		cout<<"物品"<<i + 1<<":"<<o[i]<<"件"<<endl;
	}
	return 0;
}

posted on 2015-09-19 02:00  hh6plus  阅读(260)  评论(0编辑  收藏  举报