背包问题
给定一个载重量为M的背包,考虑n个物品,其中第i个物品的重量 wi ,价值vi (1≤i≤n),要求把物品装满背包,且使背包内的物品价值最大。
(1)当作0-1背包问题,用动态规划算法,获得最优值220;
(2)当作0-1背包问题,用贪心算法,按性价比从高到底顺序选取物品,获得最优值160。由于物品不可分割,剩下的空间白白浪费。
(3)当作背包问题,用贪心算法,按性价比从高到底的顺序选取物品,获得最优值240。由于物品可以分割,剩下的空间装入物品3的一部分,而获得了更好的性能。
数据结构:
struct bag{
int w; //物品的重量
int v; //物品的价值
double c; //单位重量的价值,v/w
};
降序排序:
bool cmp(bag a, bag b){
return a.c >= b.c;
}
背包问题贪心算法:
double knapsack(int n, bag a[], double c){
double cleft = c; //背包的剩余容量
int i = 0;
double b = 0; //背包内物品的总价值获得的价值
//当背包还能完全装入物品i
while(i<n && a[i].w<cleft) {
cleft -= a[i].w;
b += a[i].v;
i++;
}
//装满背包的剩余空间
if (i<n)
b += 1.0*a[i].v*cleft/a[i].w;
return b;
}
最优装载问题
有一批集装箱要装上一艘载重量为c的轮船,其中集装箱i的重量为wi。最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船(件数最多)。
采用重量最轻者先装的贪心选择策略
template<class Type>
void Loading(int x[], Type w[], Type c, int n){
int *t = new int [n+1];
Sort(w, t, n);//t 存储的是按重量排好序的集装箱的序号
for (int i = 1; i <= n; i++)
x[i] = 0;
for (int i = 1; i <= n && w[t[i]] <= c; i++) {
x[t[i]] = 1; c - = w[t[i]];
}
}