1.问题:给定初始资金,有N个项目,每个项目有成本和纯利润,在其中选取k个项目,求获得的最大利润。
例如:有项目(花费,利润):[1,2],[1, 4],[5, 4],[5,6],初始资金是1,可做最大项目是2个。
那么选取符合成本的项目[1,2], [1, 4],选取利润大的项目[1,4],得到总资金5。然后在[5, 4],[5,6]选取[5,6]得到最后的总资金11。
解:
- 根据花费建立比较器,将项目存放到小根堆中,根据利润建立比较器,建立大根堆。
- 循环k次,将花费小于等于总资金的项目放入大根堆,取出 大根堆的项目,累加利润,大根堆为空或者循环完k次结束计算。
/**
* 根据项目的花费和利润,在初始资金和限制max项目数的情况下,获得最大利润
* @param data
* @param initMoney
* @param maxProject
* @return
*/
public static int maxMoney(ProjectInfo[] data, int initMoney, Integer maxProject) {
PriorityQueue<ProjectInfo> minCostQueue = new PriorityQueue<>(Comparator.comparingInt(o -> o.cost));
PriorityQueue<ProjectInfo> mxProfitsQueue = new PriorityQueue<>((o1,o2) -> o2.profits - o1.profits);
//小根堆组织说有花费的项目
minCostQueue.addAll(Arrays.asList(data));
//循环挑选项目k次
int sumMoney = initMoney;
for (int i = 0; i < maxProject; i++) {
//选取符合花费条件的项目
while (!minCostQueue.isEmpty() && minCostQueue.peek().cost <= sumMoney) {
mxProfitsQueue.add(minCostQueue.poll());
}
if (mxProfitsQueue.isEmpty()) {
return sumMoney;
}
sumMoney += mxProfitsQueue.poll().profits;
}
return sumMoney;
}
@AllArgsConstructor
public static class ProjectInfo {
private Integer cost;
private Integer profits;
}
2. 问题:按数组划分金条,每次花费的为金条长度的代价,求最小花费。
例如:将金条按照[10,20,30]划分,那么总长度是60.那么可以采取的方案是:
60 -> 30,30 -> 10,20; 花费:60 + 10 + 20 = 90;
60 ->10, 50 -> 20,30; 花费: 60 + 20 + 30 = 110;
60 ->20, 40 -> 10,30; 花费:60 + 10 + 30 = 100;
可见按照第一种的方式成本是最小的。
解:
- 按照花费建立小顶堆,取出小顶堆的元素累加求和,得到最后的总花费;
public static int lessMoney(Integer[] datas) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
queue.addAll(Arrays.asList(datas));
int sum = 0;
while (queue.size() > 1) {
sum += queue.poll() + queue.poll();
queue.add(sum);
}
return sum;
}
问题:最优的方式安排会议
解:
- 按照会议结束时间建立比较器,将会议放入小顶堆;
- 循环所有会议,符合限制开始时间时结果加一,然后限制开始时间后移到当前会议的结束时间。
//哪个会议的结束时间早就安排在前面
public static int arrangeProject(Integer timePoint, Cnference[] cnferences) {
int result = 0;
Arrays.stream(cnferences).sorted();
for (int i = 0; i < cnferences.length; i++) {
if (timePoint <= cnferences[i].start) {
result++;
timePoint = cnferences[i].end;
}
}
return result;
}
public static class Cnference implements Comparator<Cnference> {
private Integer start;
private Integer end;
@Override
public int compare(Cnference o1, Cnference o2) {
return o1.end - o2.end;
}
public Cnference(Integer start, Integer end) {
this.start = start;
this.end = end;
}
}

被折叠的 条评论
为什么被折叠?



