动态规划系列(2)——01背包问题的动态规划解法

问题:有n 个物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?  

/*
 * Dynamic Programming : 0-1 package problem
 */

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

struct Item {
	int id, w, v;
	Item(int _i, int _w, int _v) : id(_i), w(_w), v(_v) {}
}; 

int packageProblem(vector<Item> &itemList, int capacity, int itemNumber, vector<Item> &ans) {
	int **map = new int*[itemNumber+1];
	for(int i = 0; i < itemNumber+1; i++) {
		map[i] = new int[capacity+1];
		memset(map[i], 0, sizeof(int)*(capacity+1));
	}
	
	for(int i = 0; i < itemNumber+1; i++) {
		for(int j = 1; j < capacity + 1; j++){
			if(i == 0 || j == 0) map[i][j] = 0;
			else if(j < itemList[i - 1].w) {
				map[i][j] = map[i-1][j];
			}
			else if(j >= itemList[i - 1].w) {
				map[i][j] = max(map[i-1][j-itemList[i - 1].w] + itemList[i - 1].v, map[i-1][j]);
			}
		}
	}
	for(int i = 0; i < itemNumber+1; i++) {
		for(int j = 0; j < capacity + 1; j++) {
			cout << map[i][j] << "\t";
		}
		delete [] map[i];
		cout << endl;
	}
	delete [] map;
	
	return map[itemNumber][capacity];
}

int main() {
	int capacity, itemNumber;
	vector<Item> itemList, ans;
	cin >> itemNumber >> capacity;
	for(int i = 0; i < itemNumber; i++) {
		int tempID, tempW, tempV;
		cin >> tempID >> tempW >> tempV;
		itemList.push_back(Item(tempID, tempW, tempV));
	}
	
	cout << packageProblem(itemList, capacity, itemNumber, ans);
	return 0;
} 

通过动态规划系列1和2的练习,总结出:动态规划需要记录的数据的数组的维数和需要记录的变量个数有关,如在斐波那契数列问题中,只需要一个一维数组记录即可,因为只有一个变量。而在01背包问题中,需要一个二维数组记录,这是因为除了当前考虑的物品i之外,还有背包容量这一变量。因此在实现动态规划算法的过程中,通过状态转移方程中的变量个数即可确定需要申请的标记数组的维数。

发布了115 篇原创文章 · 获赞 96 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/qq_26822029/article/details/90055590
今日推荐