第一题
思路:大根堆
public class 第一题12 {
public static void main(String[] args) {
int[][] stones = {{0,4,7},{1,3,4},{0,7,6},{0,1,5}};
int res = minCost(stones);
System.out.println(res);
}
static class Node{
public int red;
public int blue;
public Node(int red,int blue){
this.red = red;
this.blue = blue;
}
}
public static int minCost(int[][] stones){
int n = stones.length;
if (n % 2 == 1){
return -1;
}
int red = 0;
int red_sum = 0;
int blue = 0;
int blue_sum = 0;
int stone_sum = 0;
PriorityQueue<Node> queue = new PriorityQueue<>(new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
int del1 = o1.red - o1.blue;
int del2 = o2.red - o2.blue;
return del2 - del1;
}
});
for (int i = 0;i < n;i++){
if (stones[i][0] == 1){
red++;
}else if (stones[i][0] == 2){
blue++;
}else {
stone_sum++;
red_sum += stones[i][1];
queue.add(new Node(stones[i][1],stones[i][2]));
}
}
if (red > n / 2 || blue > n / 2){
return -1;
}
int adv_red = n / 2 - red;
int adv_blue = stone_sum - adv_red;
while (adv_blue > 0){
Node poll = queue.poll();
red_sum = red_sum + poll.blue - poll.red;
adv_blue--;
}
return red_sum;
}
}
第二题
思路:根据n和m的值来进行方法选取:
1.如果n非常大,使用小根堆
2.如果m非常大,使用二分答案
public class 第二题12 {
//小根堆
public static int minWaitingTime1(int[] arr, int m) {
if(arr == null || arr.length == 0){
return -1;
}
PriorityQueue<int[]> queue = new PriorityQueue<>((a,b) -> a[0] - b[0]);
for (int i = 0;i < arr.length;i++){
queue.add(new int[]{0,arr[i]});
}
for (int i = 0;i < m;i++){
int[] poll = queue.poll();
poll[0] += poll[1];
queue.add(poll);
}
return queue.peek()[0];
}
//二分答案
public static int minWaitingTime2(int[] arr, int m) {
if (arr == null || arr.length == 0) {
return -1;
}
int best = Integer.MAX_VALUE;
for (int num : arr) {
best = Math.min(best, num);
}
int left = 0;
int right = best * m;
int near = 0;
while (left <= right) {
int mid = (left + right) / 2;
int cover = 0;
for (int num : arr) {
cover += (mid / num) + 1;
}
if (cover >= m + 1) {
near = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return near;
}
}