算法(十)贪心算法

题目描述:

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

Input: k=2, W=0, Profits=[1,2,3], Capital=[0,1,1].

Output: 4

Explanation: 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循环在这种测试数据下基本不会运行,所以大大提高了时间复杂度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值