C++项目最大收益(贪心问题)

1. 题目描述

  1. 输入: 参数1,正数数组costs; 参数2,正数数组profits;参数3,正数k; 参数4,正数m;
    costs[i]表示i号项目的花费, profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润) ,k表示你不能并行、只能串行的最多做k个项目 m表示你初始的资金。说明:你每做完一个项目,马上获得的收益,可以支持你去做下一个项目。
  2. 输出: 你最后获得的最大钱数。

2. 思路

给定一个初始投资资金,给定N个项目,想要获得其中最大的收益,并且一次只能做一个项目。这是一个贪心策咯的问题,按照花费的多少放到一个小根堆里面,然后要是小根堆里面的头节点的花费少于给定资金,就将头节点一个个取出来,放到按照收益的大根堆里面,这样就然后将大根堆的堆顶弹出,将其加到初始资金上,这样我们就可以从小跟堆中解锁新的项目了,然后重复这个过程。如果遇到大跟堆中为空,我们就直接弹出来就可以啦。

3. 基础数据结构

struct Finance {
    int cost;
    int profit;
};

我们使用一个结构体包含我们的花费和收益。

为了实现花费的小跟堆和收益的大跟堆,我们使用std::priority_queue,只要对第三个参数进行重载,这里是结构体了,所以我们自定义cmp函数。

// cost minHeap
struct cmp1 {
    bool operator () (Finance& f1, Finance& f2) {
        return f1.cost > f2.cost;
    }
};
// profit maxHeap
struct cmp2 {
    bool operator () (Finance& f1, Finance& f2) {
        return f1.profit < f2.profit;
    }
};

4. 完整代码

#include 
#include 
#include 

struct Finance {
    int cost;
    int profit;
};

// cost minHeap
struct cmp1 {
    bool operator () (Finance& f1, Finance& f2) {
        return f1.cost > f2.cost;
    }
};
// profit maxHeap
struct cmp2 {
    bool operator () (Finance& f1, Finance& f2) {
        return f1.profit < f2.profit;
    }
};

int IPO(std::vector<int>& costs, std::vector<int>& profits, int k, int m) {
    std::priority_queue<Finance, std::vector<Finance>, cmp1> costsMinHeap;
    std::priority_queue<Finance, std::vector<Finance>, cmp2> profitsMaxHeap;
    Finance* FinanceNode = new Finance[profits.size()];
    for (int i = 0; i < profits.size(); ++i) {
        FinanceNode[i].cost = costs[i];
        FinanceNode[i].profit = profits[i];
    }
//    int ipoProfit = 0;
    for (int i = 0; i < profits.size(); ++i) {
        costsMinHeap.push(FinanceNode[i]);
    }
    for (int i = 0; i < k; ++i) {
        while (!costsMinHeap.empty() && costsMinHeap.top().cost <= m) {
            profitsMaxHeap.push(costsMinHeap.top());
            costsMinHeap.pop();
        }
        if (profitsMaxHeap.empty()) {
            return m;
        }

        m += profitsMaxHeap.top().profit;
        profitsMaxHeap.pop();
    }

    delete [] FinanceNode;
    return m;
}

int main()
{
    std::vector<int> costs = {5, 10, 100};
    std::vector<int> profits = {7, 8, 60};
    int ipoProfits = IPO(costs, profits, 4, 20);
    std::cout << "IPO: " << ipoProfits << std::endl;
    return 0;
}

C++项目最大收益(贪心问题)_第1张图片

5. 参考文献

  1. 左神算法-贪婪算法(项目收益)【c++实现】
  2. 项目获得的最大收益(贪心)

大跟堆+小跟堆还是很好用的。

你可能感兴趣的:(C++)