zoukankan      html  css  js  c++  java
  • 贪心算法-项目收益问题

    题目:

    输入:
    正数数组costs    :costs[i]表示i号项目的花费
    正数数组profits  :profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润)
    正数k :能串行的最多做k个项目
    正数m :初始的资金
    输出:
    你最后获得的最大钱数。

    solution:

    1、建立一个小根堆(被锁池,按照起始资金进行排序,不分利润大小)和一个大根堆(解锁池,按照利润进行排序)
    2、先把所有项目放入小根堆
    3、小根堆中弹出所有满足起始资金的一批,放入大根堆
    4、大根堆弹出一个项目(获得了利润最大的一个项目A)
    5、根据项目A的钱去小根堆中解锁能做的项目
    循环2,3,4

    代码实现 

    package Algorithms.greed;
    
    
    import java.util.Comparator;
    import java.util.PriorityQueue;
    
    public class IPO {
    
        //项目模型
        public static class Node {
            public int p; //利润
            public int c; //花费
    
            public Node(int p, int c) {
                this.p = p;
                this.c = c;
            }
        }
    
        //根据花费构建小根堆 的比较器
        public static class MinCostComparator implements Comparator<Node> {
    
            @Override
            public int compare(Node o1, Node o2) {
                return o1.c - o2.c;
            }
        }
    
        //根据利润构建大根堆 的比较器
        public static class MaxProfitComparator implements Comparator<Node> {
    
            @Override
            public int compare(Node o1, Node o2) {
                return o2.p - o1.p;
            }
        }
    
        public static int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {
    
            //构建项目
    //        Node[] nodes = new Node[Profits.length];
    //        for (int i = 0; i < Profits.length; i++) {
    //            nodes[i] = new Node(Profits[i], Capital[i]);
    //        }
    
            PriorityQueue<Node> minCostQ = new PriorityQueue<>(new MinCostComparator());
            PriorityQueue<Node> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());
            for (int i = 0; i < Profits.length; i++) { //把所有项目扔到被锁池中(花费构建的小根堆)
                minCostQ.add(new Node(Profits[i], Capital[i]));
            }
            for (int i = 0; i < k; i++) { //进行k轮
                //符合启动资金的项目全部解锁
                while (!minCostQ.isEmpty() && minCostQ.peek().c <= W) {
                    maxProfitQ.add(minCostQ.poll());
                }
                if (maxProfitQ.isEmpty()) {  //无项目可挑(启动资金不满足后面的项目)
                    return W;
                }
                W += maxProfitQ.poll().p; //利润累加
            }
            return W;
        }
    
    }
  • 相关阅读:
    匿名对象、栈空间和堆空间,String的两种实例化方式的比较,"=="和"equals()"的区别
    间接调用父类私有成员方法、通过抽象类可以达到不需要实现接口所有方法的目的
    this关键字、构造快和静态块
    java可变参数的支持和foreach输出
    java-循环结构体
    switch和if else的区别和应用
    作用域对象
    JavaWeb1
    JavaScript 表单编程
    好久不见
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/15143416.html
Copyright © 2011-2022 走看看