LeetCode 502. IPO

来源:互联网 发布:淘宝客分佣app制作 编辑:程序博客网 时间:2024/05/20 17:42

502. IPO

一、问题描述

Suppose LeetCode will start its IPO soon. In order to sell a good price of its shares to Venture Capital, LeetCode would like to work on some projects to increase its capital before the IPO. Since it has limited resources, it can only finish at most k distinct projects before the IPO. Help LeetCode design the best way to maximize its total capital after finishing at most k distinct projects.

You are given several projects. For each project i, it has a pure profit Pi and a minimum capital of Ci is needed to start the corresponding project. Initially, you have W capital. When you finish a project, you will obtain its pure profit and the profit will be added to your total capital.

To sum up, pick a list of at most k distinct projects from given projects to maximize your final capital, and output your final maximized capital.

二、输入输出

Example 1:

Input: k=2, W=0, Profits=[1,2,3], Capital=[0,1,1].Output: 4Explanation: Since your initial capital is 0, you can only start the project indexed 0.             After finishing it you will obtain profit 1 and your capital becomes 1.             With capital 1, you can either start the project indexed 1 or the project indexed 2.             Since you can choose at most 2 projects, you need to finish the project indexed 2 to get the maximum capital.             Therefore, output the final maximized capital, which is 0 + 1 + 3 = 4.

Note:

  1. You may assume all numbers in the input are non-negative integers.
  2. The length of Profits array and Capital array will not exceed 50,000.
  3. The answer is guaranteed to fit in a 32-bit signed integer.

三、解题思路

贪心算法

  • 这道题真是学到了很多,最重要的是priority_queue的使用,他可以很方便的帮你对一对数按照某个次序进行排序。你要做的只是把他们加进去就行了,根本不用再手动排序。Priority_queue的排序方法有两种:仿函数,重写operator< 具体参考这篇文章 写的很好
  • 这道题有一点坑,就是买东西是不花钱的,只要你能买的起,也是无语了,或者是我题目没读懂?
  • Step1: 我们先把profits capital成对的放到prority_queue里面,按照capital 从小到大的顺序排序。
  • Step2: 依次比较capital 和W 找到前面那些我们能买的起的(capital <=W)把这些放到另外一个priority_queue中,这个queue是按照profits从大到小排序的。这样我们就保证了这里面全都是你买的起的,而且队列前面的收益最大。那么就拿出队列头的一个元素,并把profits加到W上。
  • 重复Step1 Step2 直到k为0 或者 profits的队列为空(说明一个都买不起,或者全部买完了)返回W就行了
  • 总结:要学会使用priority_queue 真的非常好用。你不用再去sort只是简单的push就已经是按照你想要的进行排序过了的,主要是效率很高,复杂度大大降低了。遇到两个数组一起遍历并且相互产生影响的时候很可能是非常好的选择。另外,注意可以多个优先级队列一起使用。
class Solution {public:    struct Node{        int profits, capital;        Node(int p, int c): profits(p),capital(c){}    };    struct CapitalSmlToBig{        bool operator()(const Node& lhs, const Node& rhs)const{            return lhs.capital > rhs.capital;        }    };    struct ProfitBigToSml{        bool operator()(const Node& lhs, const Node& rhs)const{            return (lhs.profits < rhs.profits);        }    };    int findMaximizedCapital(int k, int W, vector<int>& Profits, vector<int>& Capital) {        priority_queue<Node, vector<Node>, CapitalSmlToBig> cq;        priority_queue<Node, vector<Node>, ProfitBigToSml> pq;        for (int i = 0, n = Profits.size(); i < n; ++i) {            cq.push(Node(Profits[i], Capital[i]));        }        while(k>0){            while(!cq.empty() && cq.top().capital <= W){                Node cnode = cq.top(); cq.pop();                pq.push(Node(cnode.profits, cnode.capital));            }            if(pq.size() == 0)return W;            W += pq.top().profits;            pq.pop();            k--;        }        return W;    }};
原创粉丝点击