问题

标准贪心问题

输入:
参数1,正数数组costs ;
参数2,正数数组profits ;
参数3, 正数k ;
参数4,正数m ;

costs[i]表示i号项目的花费,
profits[i]表示i号项目在扣除花 费之后还能挣到的钱(利润),
k表示你不能并行、只能串行的最多 做k个项目,
m表示你初始的资金 。

说明:你每做完一个项目,马上获得的收益,可以支持你去做下 一个 项目。 输出: 你最后获得的最大钱数。

分析

注意!!!
这个题目的意思是,每次做完是不减成本的,只考虑在能做范围内收益最高!!!
首先每个项目包括两个属性:花费成本 cost 和利润 profile,然后将所有的项目放入数组中。
然后将数组中所有的项目按照花费成本的大小形成一个小根堆,接着挨着从小根堆中弹出头部,只要花费成本小于初始资金(W)就都弹出,(弹出来的表示在当前资金下可以做的任务),然后将弹出的元素按照收益的高低放入大根堆中(则收益越高越优先做),每次只做大根堆的堆头部的任务,做完任务之后初始资金发生变化,再次从小根堆中弹出符合的元素进入大根堆,以此类推。直到大根堆中没有元素或者达到了最大 K 次就结束。

示例:以下任务的初始资金为:7

cost: 5 10 6 20

profile:3 2 4 9

首先将所有的项目放入小根堆,然后通过比较 cost 和初始资金,则首先放入大根堆中是: 6,4 和 5,3,先做堆顶项目6,4,做完之后收益变为:11,则任务 10,2 可以做了,现在大根堆中为:5,3;10,2,先做 5,3 任务,收益变为 14,没有新的任务可以加入大根堆中,则继续做大根堆中任务:10,2,昨晚之后收益变为:16,还是没有新的项目可以加入大根堆,这时候大根堆没有任务可以完成了,则最终停止。

实现

package MyExc;

import org.junit.Test;

import java.util.*;

//定义大根堆比较器
class myIntegerCpmparator implements Comparator<Integer>{

    @Override
    public int compare(Integer o1, Integer o2) {
        return o2.compareTo(o1);
    }
}

public class MaxProfits {
    public int maxProfits(int[] conts,int[] profits,int k,int m){
        //定义返回的最大利润
        //int maxProfits = 0;
        //定义进行的项目个数
        int i = 0;
        //定义当前的可用资金
        int M = m;

        PriorityQueue<Integer> BigHeap = new PriorityQueue<>(new myIntegerCpmparator());
        PriorityQueue<Integer> SmallHeap = new PriorityQueue<>();


        //建立map
        Map<Integer,Integer> map = new HashMap<>();
        for(int n = 0;n<conts.length;n++){
            map.put(conts[n],profits[n]);
        }

        //先按照成本进入小根堆
        for(int j:conts){
            SmallHeap.add(j);
        }

        while(i<k&&!SmallHeap.isEmpty()){
            //满足条件弹出小根堆全部进入大根堆
            while(SmallHeap.peek()<M){
                BigHeap.add(map.get(SmallHeap.poll()));
            }
            //大根堆弹出,更新可用资金
            if(BigHeap.isEmpty())
                break;
            M +=BigHeap.poll();
            i++;
        }


        return M;
    }


    @Test
    public void run(){
        int[] costs = {5,10,6,20};
        int[] profits = {3,2,4,9};
        int res = maxProfits(costs,profits,4,7);
        System.out.println(res);
    }
}