假设 力扣(LeetCode)即将开始其 IPO。为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k 个不同的项目。帮助 力扣 设计完成最多 k 个不同项目后得到最大总资本的方式。
给定若干个项目。对于每个项目 i,它都有一个纯利润 Pi,并且需要最小的资本 Ci 来启动相应的项目。最初,你有 W 资本。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。
总而言之,从给定项目中选择最多 k 个不同项目的列表,以最大化最终资本,并输出最终可获得的最多资本。
示例 1:
输入: k=2, W=0, Profits=[1,2,3], Capital=[0,1,1].
输出: 4
解释:
由于你的初始资本为 0,你尽可以从 0 号项目开始。
在完成后,你将获得 1 的利润,你的总资本将变为 1。
此时你可以选择开始 1 号或 2 号项目。
由于你最多可以选择两个项目,所以你需要完成 2 号项目以获得最大的资本。
因此,输出最后最大化的资本,为 0 + 1 + 3 = 4。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ipo
int cmp(const void *_a, const void *_b)
{
int* a = (int *)_a;
int* b = (int *)_b;
if (*a - *b == 0) {
return *(b + 1) - *(a + 1);
}
return *a - *b;
}
int findMaximizedCapital(int k, int W, int* Profits, int ProfitsSize, int* Capital,int CapitalSize)
{
int *capitalProfit = (int *)malloc(sizeof(int) * ProfitsSize * 2);
for (int i = 0; i < ProfitsSize; i++) {
capitalProfit[2 * i] = Capital[i];
capitalProfit[2 * i + 1] = Profits[i];
}
qsort(capitalProfit, ProfitsSize, sizeof(int) * 2, cmp);
if (W < capitalProfit[0]) {
free(capitalProfit);
return 0;
}
int left;
int right;
int mid;
int ret = W;
for (int i = 0; i < k; i++) {
left = 0;
right = ProfitsSize - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (capitalProfit[2 * mid] <= ret) { //可能存在资金一样的情况
left = mid + 1;
} else {
right = mid;
}
}
//printf("%d---", right);
if ((left == right) && (capitalProfit[2 * left] <= ret)) {
left++;
}
int maxProfit = capitalProfit[1];
int maxId = 0;
int j;
for (j = left - 1; j >=0; j--) {
if (maxProfit < capitalProfit[2 * j + 1]) {
maxProfit = capitalProfit[2 * j + 1];
maxId = j;
}
}
ret += maxProfit;
if (ProfitsSize - maxId - 1 > 0) {
memmove(&capitalProfit[2 * maxId], &capitalProfit[2 * maxId + 2],
(ProfitsSize - maxId - 1) * 2 * sizeof(int));
}
ProfitsSize--;
if (ProfitsSize <= 0) {
break;
}
//printf("%d, %d\n", maxProfit, ret);
}
free(capitalProfit);
return ret;
}