题目(Description):
已知背包的容量为 C C C和 n n n件物品。第i件物品的重量为 w i w_i wi,价值为 v i v_i vi,如何选择装入背包的物品,使得装入背包中物品的总价值最大?
输入(Input):
(1)物品的总数量;
(2)背包的最大容量;
(3)第1件物品的重量和第1件物品的价值;
(4)第2件物品的重量和第2件物品的价值;
…
输出(Output):
最优解。
示例(Sample):
输入(Input):
3
50
20 60
30 120
10 50
输出(Output):
最优解为(0.5,1,1)
思路
采用贪心策略:优先选择单位价值最大的物品放入背包
算法实现
#include<iostream>
#include<algorithm>
using namespace std;
#define N 20
struct item {
int weight;
int value;
int index;
};
bool cmp(const struct item i1, const struct item i2) {
return ((double)i1.value/(double)i1.weight) >
((double)i2.value/(double)i2.weight);
}
int KnapSack(struct item items[], int n, int C) {
double x[N]={0};
int i,value=0;
for(i=0; items[i].weight < C; i++) {
x[items[i].index]=1;
value += items[i].value;
C -= items[i].weight; //剩余容量
}
//物品i部分装入
x[items[i].index] = (double)C/items[i].weight;
value += x[items[i].index]*items[i].value;
cout << "最优解为(";
for(i=0; i<n-1; i++)
cout <<x[i] <<",";
cout<< x[i] << ")"<<endl;
//cout << value;
return value;
}
int main()
{
int n, C, i;
struct item items[N];
cin >> n >> C; // 物品数量 背包容量
for(i=0; i<n; i++) {
cin >> items[i].weight >> items[i].value;
items[i].index=i;
}
sort(items,items+n,cmp);
KnapSack(items,n,C);
}
小结
在背包价值增长和背包容量消耗两者之间寻找平衡。
排序是关键,时间复杂度取决于排序算法,因为目前内部排序算法最好的时间复杂度是
O
(
n
l
o
g
2
n
)
O(nlog_2n)
O(nlog2n),而在有序的情况下,时间性能最坏的情况就是所有背包容量足以装入所有物品,最坏的时间复杂性是
O
(
n
)
O(n)
O(n) 。
这里我是用STL的sort算法(查阅资料知道STL的sort是比较智能的,是结合快速排序-插入排序-堆排序三种排序算法的一种排序实现)