项目利润(贪心)

分析:将所有的项目按照花费由小到大放入小根堆,如果当前钱数能做的项目,按照利润由大到小的放入大根堆,每做一个项目都重复的往大根堆里丢能做的项目,直到大根堆为空,或者k个项目做完为止

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

/**
 * @author Oxygen
 * @date 2018年9月2日
 */
public class Main{
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int W = scanner.nextInt(); // 本金
		int K = scanner.nextInt(); // 表示不能并行、只能串行的最多做k个项目
		int[] cost = { 10, 5, 14, 25 }; // 项目花费
		int[] pro = { 4, 6, 8, 15 }; // 项目利润

		process(W, K, cost, pro);
	}

	private static int process(int W, int K, int[] cost, int[] pro) {
		Node[] nodes = new Node[cost.length];
		for (int i = 0; i < cost.length; i++) {
			nodes[i] = new Node(cost[i], pro[i]);
		}
		PriorityQueue<Node> minCostQ = new PriorityQueue<>(new MinCostComparator()); // 项目花费小根堆
		for (int i = 0; i < nodes.length; i++) {
			minCostQ.add(nodes[i]);// 把所有的项目按照花费从小到大的放入小根堆
		}
		PriorityQueue<Node> maxProQ = new PriorityQueue<>(new MaxProComparator()); // 项目利润大根堆
		for (int i = 0; i < K; i++) {// 最多做k个项目
			while (!minCostQ.isEmpty() && minCostQ.peek().c <= W) {// 当满足条件时,把所有的项目按照利润从大到小的放入大根堆,解锁项目
				maxProQ.add(minCostQ.poll());
			}
			if (maxProQ.isEmpty()) {// 如果大根堆为空,即当前的money不能够完成任何项目,此时return
				return W;
			}
			W += maxProQ.poll().p;// 本金+利润
		}
		return W;
	}

}

class Node { // 项目类
	public int p;// 项目利润
	public int c;// 项目花费

	public Node(int p, int c) {
		this.p = p;
		this.c = c;
	}
}

class MinCostComparator implements Comparator<Node> {

	@Override
	public int compare(Node o1, Node o2) {
		// TODO Auto-generated method stub
		return o1.c - o2.c;
	}

}

class MaxProComparator implements Comparator<Node> {

	@Override
	public int compare(Node o1, Node o2) {
		// TODO Auto-generated method stub
		return o2.p - o1.p;
	}

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值