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 <iostream>
#include <vector>
#include <queue>

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;
}

在这里插入图片描述

5. 参考文献

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

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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最优装载问题,也称为背包问题(Knapsack Problem),在计算机科学中是一个经典的组合优化问题,通常涉及到如何在给定容量限制下,选择物品以获得最大的价值。在C++中,解决这类问题的一种常见方法是使用贪心算法,特别是针对0-1背包问题(每个物品只能取一次)。 贪心算法策略是每次选择当前状态下能够提供最大收益(价值/重量比)的物品放入背包,直到达到背包的容量。以下是使用贪心策略解决0-1背包问题的一个简单C++实现: ```cpp #include <iostream> #include <vector> // 定义物品类 struct Item { int weight; // 重量 int value; // 价值 }; // 贪心函数,返回包含在背包中的最大总价值 int greedyKnapsack(std::vector<Item>& items, int capacity) { std::sort(items.begin(), items.end(), [](const Item& a, const Item& b) { return (a.value / a.weight) > (b.value / b.weight); }); // 按价值/重量比率排序 int totalValue = 0; for (const auto& item : items) { if (capacity >= item.weight) { // 如果有足够空间,添加当前物品 totalValue += item.value; capacity -= item.weight; // 更新背包容量 } else { // 如果超出容量,选择部分物品 totalValue += item.value * (capacity / item.weight); break; // 停止添加,因为剩余容量不足以再放一个完整的物品 } } return totalValue; } int main() { std::vector<Item> items = {{60, 100}, {100, 200}, {120, 300}}; // 一些物品及其重量和价值 int capacity = 500; // 背包容量 int maxTotalValue = greedyKnapsack(items, capacity); std::cout << "Max total value with greedy approach: " << maxTotalValue << std::endl; return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值