问题描述
小R在教室里有N名学生和M名教职员工。每个教职员工的评估速度不同,评估每个学生所需的时间不同。你得到一个数组A,其中A[i]表示第i名教职员工对一名学生进行评估所需的时间(以分钟为单位)。
教职员工需要对所有学生进行评估,每名教职员工在任意时刻只能评估一名学生。评估完成后,教职员工可以立即开始评估下一名学生。你的任务是找到在这些条件下评估所有学生所需的最短总时间。
测试样例
样例1:
输入:
N = 2, M = 2, A = [3, 4]
输出:4
样例2:
输入:
N = 3, M = 2, A = [5, 7]
输出:10
样例3:
输入:
N = 5, M = 3, A = [2, 3, 5]
输出:6
思路是先对A排序再平分N名学生,剩下的优先选择花费时间少的分配;新建一个数组算他们时间,然后削高补低,从后面往前补,判断条件是时间少的那一个添加这个后的事件比当前的最大值小就行,然后一直循环,知道找不到这个合适的数就是可以结束了,用一个布尔值标记。
import java.util.Arrays;
public class Main {
public static int solution(int N, int M, int[] A) {
// PLEASE DO NOT MODIFY THE FUNCTION SIGNATURE
// write code here
Arrays.sort(A);
int[] num = new int[M];// 存老师改试卷用的时间
int i, avg = N / M, len = A.length, remain = N % M;
// 将试卷平均分给M个老师
for (i = 0; i < len; i++) {
num[i] += avg * A[i];
}
// 将剩下的试卷按排序分给了老师
for (i = 0; i < remain; i++) {
num[i] += A[i];
}
int[] maxAndIndex;
while (true) {
boolean flag = true;
maxAndIndex = findMaxinArr(num);
for (i = maxAndIndex[1] - 1; i > -1; i--) {
if (num[i] + A[i] <= num[maxAndIndex[1]] ) {
num[i] += A[i];
num[maxAndIndex[1]] -= A[maxAndIndex[1]];
flag = false;
break;
}
}
if (flag) {
break;
}
}
return maxAndIndex[0];
}
// 按最大值、这个值的索引返回一个数组
public static int[] findMaxinArr(int[] arr) {
int max = Integer.MIN_VALUE, len = arr.length, index = 0;
for (int i = 0; i < len; i++) {
if (arr[i] > max) {
max = arr[i];
index = i;
}
}
return new int[] { max, index };
}
public static void main(String[] args) {
System.out.println(solution(2, 2, new int[] { 3, 4 }) == 4);
System.out.println(solution(3, 2, new int[] { 5, 7 }) == 10);
System.out.println(solution(5, 3, new int[] { 2, 3, 5 }) == 6);
}
}