IPO问题

题目及要求如下

输入:参数1,正数数组costs 参数2,正数数组profits 参数3,正数k 参数4,正数m
costs[i]表示i号项目的花费,profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润),k表示不能并行、只能串行的最多做k个项目,m表示初始的资金
说明:每做完一个项目,马上获得的收益,可以支持你去做下一个项目。
输出:最后获得的最大钱数。

主体思路

    每次应该得到花费小于现有资金并且利润最大的项目.可以使用两个队列,一个按照花费钱数从小到大排列.将该队列中符合条件的项目全部放到另一个按照项目利润从大到小排列的队列中,每次弹出利润队列的第一个项目.具体实现如下:

第一步 : 创建结构,整合项目的花费和利润到一个主体

class Proje{
	int cost;
	int profit;
	
	Proje(int c, int p){
		this.cost = c;
		this.profit = p;
	}
}

第二步 : 创建比较器,按照项目花费从小到大和利润从大到小

class MinCostComparator implements Comparator<Proje>{
	@Override
	public int compare(Proje o1, Proje o2) {
		return o1.cost - o2.cost;
	}
}

class MaxProfitComparator implements Comparator<Proje>{
	@Override
	public int compare(Proje o1, Proje o2) {
		return o2.profit - o1.profit;
	}
}

第三步 : 主体函数

public class CostAndProfits {
	@SuppressWarnings({ "unused", "unchecked" })
	public static Integer IPO(int [] cost, int [] profit, int k, int w){
		if(cost.length != profit.length && cost == null && profit == null){
			return -1;
		}
		Proje [] pro = new Proje[cost.length];
		//构建proje结构并存放到数组中方便操作
		for(int i = 0; i < cost.length; i++){
			pro[i] = new Proje(cost[i],profit[i]);
		}
		
		//创建两个队列
		PriorityQueue<Proje> minCostQ = new PriorityQueue<Proje>(new MinCostComparator());
		PriorityQueue<Proje> maxProfitQ = new PriorityQueue<Proje>(new MaxProfitComparator());
		int  res = -1;
		
		//按照题目要求最多k次循环
		for(int i = 0; i < k; i++){
			//取出所有花费小于现有资金的项目存放到maxProfitQ
			while(!minCostQ.isEmpty() && minCostQ.peek().cost <= w){
				maxProfitQ.add(minCostQ.poll());
			}
			//如果maxProfitQ为空,证明所有项目的花费都大于了现有资金,不能继续做项目了,直接返回结果.
			if(maxProfitQ.isEmpty()){
				return res;
			}else{
				//弹出最大利润的项目
				res += maxProfitQ.poll().profit;
			}
		}
		
		return res;
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_39445556/article/details/105194920
IPO