背包算法
问题:
有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?
问题分析:
在选择装入背包的物品时,对于物品i只有两种选择,即装入背包或不装入背包。不能将物品i装入背包多次,也不能只装入物品i的一部分。假设xi表示物品i被装入背包的情况,当xi=0时,表示物品没有被装入背包;当xi=1时,表示物品被装入背包。
在决策xi时,问题处于下列两种状态之一:
1、背包容量不足以装入物品i,则xi=0,装入背包的价值不增加
2、背包容量足以装入物品i,则xi=1,装入背包的价值增加vi
在这两种情况下,装入背包的价值最大者应该是对xi决策后的价值
设计:
通过两个数组weight和value来记录物品的重量和价值。
通过两个for循环从一个商品加入背包一直到最后一个商品可以加入背包(在背包载重允许的情况下)。
for循环里只需加一个判断,判断商品重量是否小于背包载重。如果小于则重量为j时的背包此时最大价值为max(c[i-1][j],c[i-1][j-weight[i]]+value[i])。
for(int i = 1; i <= num; i++){
for(int j = 1; j <= totalweight; j++){
if(j < weight[i]){
c[i][j] = c[i-1][j];
// cout << "[" << i << "],[" << j << "]:" << c[i][j] << " ";
}else{
c[i][j] = max(c[i-1][j],c[i-1][j-weight[i]]+value[i]);
// cout << "[" << i << "],[" << j << "]:" << c[i][j];
}
}
cout << endl;
}
讲到这里其实背包算法也就已经实现了,最后只需输出c[num][totalweight]即可获得背包最大价值。
下面为源代码:
//背包算法
#include<iostream>
#include <string.h>
using namespace std;
const int MAX = 1000;
int main(){
int totalweight;
int num;
cout << "==========背包问题========" << endl;
cout << "======输入背包最大载重======" << endl;
cin >> totalweight;
cout << "========输入物品个数=======" << endl;
cin >> num;
int weight[MAX] = {0};
int value[MAX] = {0};
cout << "=====输入商品重量和价值=====" << endl;
for(int i = 1; i <= num;i++)
cin >> weight[i] >> value[i];
int c[MAX][MAX];
for(int j = 0; j <= totalweight; j++){
c[0][j] = 0;
}
for(int i = 0; i <= num; i++){
c[i][0] = 0;
}
for(int i = 1; i <= num; i++){
for(int j = 1; j <= totalweight; j++){
if(j < weight[i]){
c[i][j] = c[i-1][j];
// cout << "[" << i << "],[" << j << "]:" << c[i][j] << " ";
}else{
c[i][j] = max(c[i-1][j],c[i-1][j-weight[i]]+value[i]);
// cout << "[" << i << "],[" << j << "]:" << c[i][j];
}
}
cout << endl;
}
cout << "=====背包最大价值为=====" << endl;
cout << c[num][totalweight] << endl;
}