8.7 贪心策略例题---背包问题(最优装载问题、部分背包问题)

问题1:最优装载问题(简单)

代码:


import java.util.Arrays;
import java.util.Scanner;

public class Main {
 /* 
  */
	public static void main(String[] args) {
		//(1)输入相关数据
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();//物体数
		int c = sc.nextInt();//总重量不超过c
		int[] w = new int[n];//每个物体重量
		for(int i=0;i<n;i++) {
			w[i] = sc.nextInt();
		}
		//(2)排序
		Arrays.sort(w);
		//(3)选取尽量多的物品
		f(w,c);
	}

private static void f(int[] w, int c) {
	int sum=0;
	int cnt=0;
	for(int i=0;i<w.length;i++) {
		sum+=w[i];
		if(sum<=c) {
			cnt++;
		}else {
			break;
		}
	}
	System.out.println(cnt);
	
}
	
}

问题2:部分背包问题

每个物体可以只取走一部分: 即如果选取某物品之后总重量超过C,不选则小于C,故只需选择C所需的那一部分。

输入:

第一行:物体总数n  总重量不超过C

接下来n行 :每个物体的重量、价值

输出:

最大总价值

代码:
 


import java.util.Arrays;
import java.util.Scanner;

public class Main {
 /* 
  * 思路:(1)将每个物体的价值和重量封装在对象中,并按照单位重量的价值排序。单位重量的价值 = 物体价值/重量
  *             (2)从后向前,每次选取单位价值最大的物体
  *    (3)如果选取物体i后,总重量超过C,则选取其中的一部分,该部分的价值=C还需的重量*该物体的单位重量价值
  */
	public static void main(String[] args) {
		//(1)输入相关数据
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();//物体数
		int c = sc.nextInt();//总重量不超过c
		
		Obj[] objs = new Obj[n];
		for(int i=0;i<n;i++) {//输入每个物体的重量和价值
			objs[i] = new Obj(sc.nextInt(),sc.nextInt());
		}
		//(2)排序
		Arrays.sort(objs);
		
		//(3)选取总价值尽量高的物品
		getRes(objs,c);
	}
	
	private static void getRes(Obj[] objs, int c) {
		double maxvalue = 0;//记录总价值
		int weight=0;//记录当前已有的重量
		for(int i=objs.length-1;i>=0;i--) {
			int w = objs[i].w;
			int v = objs[i].v;
			if((weight+w)<=c) {//加上当前物体的重量不超过c
				maxvalue+=v;//价值累加
				weight+=w;//重量累加
			}else {//加上当前物体的重量超过c,则取一部分
				double p = objs[i].getPrice(v, w);
				maxvalue+=(c-weight)*p;
				break;
			}
		}//for
		System.out.println(maxvalue);
	
	}

	private static class Obj implements Comparable<Obj>{
		int w;//重量
		int v;//价值
		public Obj(int w, int v) {
			super();
			this.w = w;
			this.v = v;
		}
		public double getPrice(int v,int w) {//获取单位重量的价值
			return v/(double)w;
		}
		@Override
		public int compareTo(Obj o) {//比较单位重量的价值
			double x = this.getPrice(this.v, this.w)-o.getPrice(o.v, o.w);
			if(x==0) return 0;
			else if(x<0) return -1;
			else return 1;
		}
	}
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值