由于最近在看贪心的题,所以就刷了一下leetcode上有关贪心策略的问题,上面有一些题虽然上了锁但比较少,大部分都是免费的,也是可以刷经验的,摘录百度百科的一段话即贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。而问题的难点在于如何找到策略,如果找到的贪心策略是对的,那写代码的过程就很简单了。
题目描述:
假设 LeetCode 即将开始其 IPO。为了以更高的价格将股票卖给风险投资公司,LeetCode希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k个不同的项目。帮助 LeetCode 设计完成最多 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。
注意:
- 假设所有输入数字都是非负整数。
- 表示利润和资本的数组的长度不超过 50000。
- 答案保证在 32 位有符号整数范围内。
解题思路:输入为两个数组,分别是每个项目的收益和成本,我们用两个堆来实现获取收益的最大值的过程,由于本金为W,我们先把所有项目加入到小根堆中,将成本比W小或等于的项目加入到大根堆中,那么大根堆的堆顶元素就是但当前能获取收益最大的项目,然后将获取的收益和本金相加,重复这个过程直到做了k个项目为止。最终整体的最大收益即为每次的局部最大收益。
class Program
{
int p;
int c;
Program(int p,int c)
{
this.p=p;
this.c=c;
}
}
class Com1 implements Comparator<Program>
{
public int compare(Program o1, Program o2)
{
return o1.c - o2.c;
}
}
class Com2 implements Comparator<Program>
{
public int compare(Program o1,Program o2)
{
return o2.p-o1.p;
}
}
public int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) {
PriorityQueue<Program> min=new PriorityQueue<>(new Com1());
PriorityQueue<Program> max=new PriorityQueue<>(new Com2());
Program[] programs=new Program[Profits.length];
for(int i=0;i<Profits.length;i++)
{
programs[i]=new Program(Profits[i],Capital[i]);
}
for(int i=0;i<programs.length;i++)
{
min.add(programs[i]);
}
for(int i=0;i<k;i++)
{
while(!min.isEmpty() && min.peek().c<=W )
{
max.add(min.poll());
}
if(max.isEmpty())
return W;
W=W+max.poll().p;
}
return W;
}