贪心算法之背包问题

本文介绍了一种简单的背包问题解决方法,即物品可以分割的情况。通过计算每个物品的性价比,并按此排序来确定装入背包的最优物品组合,以实现最大价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,我们需要知道:

背包问题有两类,即物品是否可以分割。

可以分割,就是简单背包问题。

不可分割,便是另一类背包问题,即0-1背包。

以下是,简单背包问题,即物品可以分割。

问题可以描述为:

给定一组物品,每种物品都有自己的重量价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。

看完问题后,笔者有小窃喜。

呵呵,什么背包问题,每次都最贵的物品,不就解决了,还用什么算法!

but .......

选完后,笔者心里有点慌。

有些物品虽然值钱,但重量太重,平均下来,还真不怎么值钱。

所以呀,要选性价比高的玩意儿,才能够赚大钱!

看例子:

物品序号  :       1     2    3    4     5     6    7    8 

物品重量:       4    2     9    5     5     8    5    4 

物品价值:       3    8    18   6     8     20   5   6

要将方案转换成代码,z需要好好思考一波:

/**
 * 背包问题
 * 物品可分割情况
 */

class BabyThing{
	public int num; //宝物序号
	public double w; //宝物重量
	public double price; //宝物价值
	public double rate; //性价比
	
	public double jisuanRate(){
		return this.rate = price / w; //   价值/重量
	}
}

public class PackageProblem {
	public static void sortS(List<BabyThing> list){
		Collections.sort(list, new Comparator<BabyThing>(){
			@Override
			public int compare(BabyThing o1, BabyThing o2) {
				if(o1.jisuanRate() > o2.jisuanRate()){
					return -1; //o1 > o2 降序,返回-1表示 我想调整顺序,改为升序
				}
				if(o1.jisuanRate() == o2.jisuanRate()){
					return 0;
				}
				return 1;
			}
		});
	}
	
	public static void main(String[] args) {
		List<BabyThing> list = new ArrayList<BabyThing>();
		
		double n, sumW; //宝物的数量,背包重量
		@SuppressWarnings("resource")
		Scanner in = new Scanner(System.in);
		System.out.println("请输入宝物的数量、以及背包的总容量:");
		n = in.nextDouble();
		sumW = in.nextDouble();
		for(int i = 0; i < n; i++){
			BabyThing temp = new BabyThing();
			System.out.println("输入第" + (i + 1) + "个宝物的重量,价值");
			temp.num = i + 1;
			temp.w = in.nextDouble();
			temp.price = in.nextDouble();
			list.add(temp); //加入
		}
		//按照性价比排序
		sortS(list);
		for(BabyThing o : list){
			System.out.println(o.jisuanRate());
		}
		double maxPrice = 0; //当前最大价值
		for(int j = 0, len = list.size(); j < len; j++){
			if(sumW < list.get(j).w){
				maxPrice = maxPrice + sumW * list.get(j).jisuanRate();
				break;
			}else{
				sumW = sumW - list.get(j).w; //背包剩余重量
				maxPrice = maxPrice + list.get(j).price; //当前最大价值
			}
		}
		System.out.println("装入宝物的最大价值 :  " + maxPrice);
	}



 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值