以后N行每行两个数Wi和Vi,表示物品的重量和价值
2 3
3 5
4 7
思路分析:
每件物品仅有一件,可选择放或不放
可用dp[i][j]表示前 i 件物品恰放入容量为 j 的背包可获得的最大价值,则有以下的动态规划函数:
(1) dp[i][0] = dp[0][j] = 0
(2) dp[i][j] = dp[i-1][j] j<wi
dp[i][j] = max{dp[i-1][j], dp[i-1][j-w[i]]+v[i]} j>wi
在此说明 (2) 的两种情况:
情况一: 第i个物品的重量大于背包的容量,则装人前i个物品得到的最大价值和装入前i-1个物品得到的最大价是相同的,即物品i不能装入背包
情况二: 如果第i个物品的重量小于背包的容量,则会有一下两种情况:
(a)如果第 i 件放进去,则应先求得在容量为 j-w[i] 的背包中放入前 i-1 件物品的最大价值,再加上第 i 件物品的价值,就可得到总价值
(b)如果第i个物品没有装入背包,则背包中物品价值就等于把前i-1个物品装入容量为j的背包中所取得的价值。
显然,取二者中价值最大的作为把前 i 个物品装入容量为 j 的背包中的最优解。
假设现有容量10kg的背包,另外有3个物品,物品1重量为3kg,价值为4;物品2重量为4kg,价值为5;物品3重量为5kg,价值为6。
根据dp[i][j] = max{dp[i-1][j], dp[i-1][j-w[i]]+v[i]},对物体个数及背包重量进行递推,列出一个表格(见下表),表格来自
(http://blog.csdn.net/fg2006/article/details/6766384?reload)
#include <iostream>
#include <algorithm>
using namespace std;
int max(int a, int b) { return (a>b) ? a : b; }
int binaryKnapsack(int numItems, int capacity, int *w, int *v);
int main(int argc, char const *argv[]) {
int n, m;
cin >> n >> m;
int w[n], v[n];
for (int i = 0; i < n; i++) {
cin >> w[i] >> v[i];
}
int MaxWeight = binaryKnapsack(n, m, w, v);
cout << MaxWeight << endl;
return 0;
}
int binaryKnapsack(int numItems, int capacity, int *w, int *v)
{
int dp[numItems+1][capacity+1];
for (int i = 0; i <= numItems; i++) {
for (int j = 0; j <= capacity; j++) {
if(i == 0 || j == 0)
dp[i][j] = 0;
else if(w[i-1] <= j) //w、v数组的序号是从0开始的
dp[i][j] = max(dp[i-1][j-w[i-1]]+v[i-1], dp[i-1][j]);
else
dp[i][j] = dp[i-1][j];
}
}
return dp[numItems][capacity];
}