有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
这个问题的特点是:每种物品只有一件,可以选择放或者不放。
0-1背包是经典的动态规划问题。利用动态规划思想 ,子问题为:f[i][c]表示前i件物品恰放入一个容量为c的背包可以获得的最大价值。
其状态转移方程是:f[i][c]=max{f[i-1][c],f[i-1][c-w[i]]+v[i]} //这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。
解释一下:对于物品i,在最优解中有两种选择,加入背包和不加入背包。如果物品i加入背包,f[i][c] = f[i-1][c-w[i]]+v[i]; 如果物品不加入背包,f[i][c] = f[i-1][c];所以f[i][c]的最有解是两种选择中最大的那个。
#include <iostream> #include <algorithm> #include <vector> /** * Knapsack problem */ /** * [getMostValue 获得最大的价值] * @param Weight [物品重量数组] * @param Value 物品价值数组 * @param cap 背包容量 * @param size 物品个数 * @return 最大的价值 */ int getMostValue(int* Weight , int* Value, int cap,int size){ int array[cap+1], tmp[cap+1]; for(int i = 0; i < cap+1; i++){ array[i] = 0; tmp[i] = 0; } for(int i = 0; i < size; i++){ //item for(int j = 1; j < cap+1; j++){ //weight if(j >= Weight[i]) array[j] = ( (tmp[j] > tmp[j-Weight[i]] + Value[i]) ? tmp[j]:(tmp[j-Weight[i]] + Value[i])); std::cout << array[j] << "\t"; } for(int k = 0; k < cap+1; k++) tmp[k] = array[k]; std::cout << std::endl; } return array[cap]; } int main(){ int Weight[] = {1,2,3}; int Value[] = {60,100,120}; int mostvalue = getMostValue(Weight, Value, 5, 3); std::cout << "max value is " << mostvalue << std::endl; }
原文地址:http://blog.csdn.net/chenlei0630/article/details/40864583