思路: 贪心 + 大根堆
分析: 首先我们只能选择capital小于w的, 这是一个查找问题, 对此可以想到二分查找, 因此可以先对capital进行排序, 并对Profits的位置进行更新, 之后根据w会一直增大, 那么我们可以使用大根堆, 将可以购买的项目放入堆中, 选出最大值即可
class Solution {
public:
struct Node {
int x, y;
};
int binary_search(vector<Node> &v, int w) {
// 1, 1, 1, 1, 0, 0, 0
int l = 0, r = v.size() - 1;
while (l != r) {
int mid = (l + r + 1) / 2;
if (v[mid].x <= w) l = mid;
else r = mid - 1;
}
return l;
}
int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {
vector<Node> v_cap(capital.size(), {0, 0}); // x: 投资门槛, y: 获取利润
auto cmp = [&](const Node &a, const Node &b){return a.x < b.x;};
for (int i = 0; i < capital.size(); i++) v_cap[i].x = capital[i], v_cap[i].y = profits[i];
sort(v_cap.begin(), v_cap.end(), cmp);
if (w < v_cap[0].x) return 0; // 如果一个项目也没本法购买, 那么直接返回0
// 这一次从哪里加入堆
int last = 0, count = capital.size(); // last: 标记这次从哪里开始将数据放入大根堆, count表示项目的数量, 如果项目的数量小于k那么, 就跳出循环
priority_queue<int> q;
while (k-- && count--) {
int pos = binary_search(v_cap, w);
// 把之前的放入
for (int i = last; i <= pos; i++) q.push(v_cap[i].y);
last = pos + 1;
if (q.empty()) continue; // 如果堆为空, 那么就从新循环
w += q.top(); q.pop();
}
return w;
}
};