一、贪心策略
二、部分背包问题
- 问题描述:参赛者拥有容量为𝟖𝟎𝟎ml的杯子,可任选不超过体积上限的饮料进行混合,调制饮品价格为各所使用饮料的价格之和,所得饮品价格之和最高者获胜
package com.tiger.study;
public class FractionalKnapsackProblem {
public static void main(String[] args) {
int[][] pandV = {{60, 600}, {10, 250}, {36, 200}, {16, 100}, {45, 300}};
int capV = 800;
System.out.println(fractionalKnapsack(pandV, capV));
}
private static int fractionalKnapsack(int[][] priceAndV, int capV) {
double[] costEffec = new double[priceAndV.length];
for (int i = 0; i < priceAndV.length; i++) {
costEffec[i] = ((double) priceAndV[i][0] / (double) priceAndV[i][1]);
}
sortCostEffec(costEffec, 0, costEffec.length - 1);
int price = 0;
for (int i = 0; i < costEffec.length; i++) {
for (int i1 = 0; i1 < priceAndV.length; i1++) {
double temp = (double) priceAndV[i1][0] / (double) priceAndV[i1][1];
if (temp == costEffec[i]) {
if (capV >= priceAndV[i1][1]) {
capV -= priceAndV[i1][1];
price += priceAndV[i1][0];
break;
} else {
price += (capV * temp);
capV = 0;
break;
}
}
}
if (capV == 0) {
break;
}
}
return price;
}
private static void sortCostEffec(double[] costEf, int left, int right) {
if (left >= right) {
return;
}
int mid = (left + right) / 2;
sortCostEffec(costEf, left, mid);
sortCostEffec(costEf, mid + 1, right);
partition(costEf, left, mid, right);
}
private static void partition(double[] costEf, int left, int mid, int right) {
double[] result = new double[right - left + 1];
int left_head = left, right_head = mid + 1;
int count = 0;
while (left_head <= mid && right_head <= right) {
if (costEf[left_head] > costEf[right_head]) {
result[count++] = costEf[left_head++];
} else {
result[count++] = costEf[right_head++];
}
}
if (left_head <= mid) {
for (int i = left_head; i <= mid; i++) {
result[count++] = costEf[left_head++];
}
}
if (right_head <= right) {
for (int i = right_head; i <= right; i++) {
result[count++] = costEf[right_head++];
}
}
for (int i = 0; i < result.length; i++) {
costEf[left + i] = result[i];
}
}
}