贪心算法案例-分数背包问题
贪心算法经典案例-分数背包问题
问题描述
n个物品都是液体,有重量和价值:
现在你需要拿走10升的液体
每次可以不拿,全拿,或拿一部分,问怎么拿才能获取最高的价值
编号 重量(升) 价值 物品
0 4 24 水
1 8 160 牛奶
2 2 4000 五粮液
3 6 108 可乐
4 1 4000 茅台
算法分析:
既然在有限的容量里获取尽可能多的价值,那么我们可以求出每个物品的单价,即每一升物品的价值是多少,然后将单价从大到小进行排序,优先获取单价最大的物品,获取完之后,再获取剩下单价最大的液体,直到获取液体的数量达到10升。
代码如下:
private static void select(Item[] items, int total) {
// 根据物品的单位价值进行降序排序
Arrays.sort(items, Comparator.comparingInt(Item::unitValue).reversed());
int max = 0; // 记录最大价值
// 由大到小依次选择商品
for (Item item: items) {
System.out.println(item);
if (total >= item.weight) { // 当前需要的总生数小于液体的总升数,可以购买全部该商品
// 可以拿
total -= item.weight; // 重新计算买完该商品后还剩下可用购买升数
max += item.value; // 更新最大价值
} else {
// 拿不完(如果全拿则超出了)--> 只能拿一部分(也就是拿剩下升数的该商品)
max += (total * item.unitValue());
break;
}
}
System.out.println("最大价值:"+max);
}
测试
编写主方法进行测试
public class Exercise {
public static void main(String[] args) {
Item[] items = new Item[]{
new Item(0, 4, 24),
new Item(1, 8, 160),
new Item(2, 2, 4000),
new Item(3, 6, 108),
new Item(4, 1, 4000)
};
select(items, 10);
}
static class Item {
int index; // 物品编号
int weight; // 物品总重量
int value; // 物品总价值
public Item(int index, int weight, int value) {
this.index = index;
this.weight = weight;
this.value = value;
}
// 计算每一个商品的单位价值
public int unitValue() {
return value / weight;
}
@Override
public String toString() {
return "Item{" +
"index=" + index +
", weight=" + weight +
", value=" + value +
'}';
}
}
}
运行结果如下:
Item{index=4, weight=1, value=4000}
Item{index=2, weight=2, value=4000}
Item{index=1, weight=8, value=160}
最大价值:8140
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2021-09-28 9-threadLocal