算法(十)贪心算法

来源:互联网 发布:爱伦坡 乌鸦 知乎 编辑:程序博客网 时间:2024/06/05 19:58

题目描述:

由于时间有限你只可以完成k个项目,你目前有资金W,完成每个项目可以净收益Profits[],每个项目需要投资 Capital[]。问最后的资金最多是多少?

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.

解题思路:

这道题目其实不难,使用贪心算法的思想,每次选取在资金范围内收益最高的项目即可。代码如下:

class Solution {public:    int findMaximizedCapital(int k, int W, vector<int>& Profits, vector<int>& Capital) {        for (int i = 0; i < k; ++i) {            int maxProfit = -1, project = -1;            for (int j = 0; j < Capital.size(); ++j) {                if (Capital[j] <= W && Profits[j] > maxProfit) {                    maxProfit = Profits[j];                    project = j;                }            }            if (maxProfit != -1) {                W += maxProfit;                //用迭代器删除指定元素                std::vector<int>::iterator it = Profits.begin() + project;                Profits.erase(it);                std::vector<int>::iterator it2 = Capital.begin() + project;                Capital.erase(it2);            }            else {                break;            }        }        return W;    }};

但是在LeetCode上运行最后会超时,原因是最后一个测试数据过大,并且初始资金就足够完成任一项目,所以用代码如下可以节省时间:

class Solution {public:    int findMaximizedCapital(int k, int W, vector<int>& P, vector<int>& C) {        priority_queue<int> low;      // P[i]'s within current W        multiset<pair<int, int>> high; // (C[i],P[i])'s' outside current W        for (int i = 0; i < P.size(); ++i) // initialize low and high            if (P[i] > 0)                 if (C[i] <= W)                     low.push(P[i]);                 else high.emplace(C[i], P[i]);        while (k-- && low.size()) {            W += low.top(), low.pop(); // greedy to work on most profitable first            for (auto i = high.begin(); high.size() && i->first <= W; i = high.erase(i))             low.push(i->second);        }        return W;    }};

while循环内部的for循环在这种测试数据下基本不会运行,所以大大提高了时间复杂度。

原创粉丝点击