用java分治法编写下列问题:小明上学,老师布置了 n 个作业,每个作业恰好需要一天做完,每个作业都有最后提交时间ti及其逾期的扣分ki。已知作业n = 3,每个作业的最后提交时间t = [1,3,1],作业逾期扣分k = [6,2,3]。以输入n = 0时作为结束,请给出小明做作业的顺序,以便扣最少的分数。
时间: 2024-02-20 16:01:55 浏览: 69
好的,下面是Java代码实现:
```
import java.util.*;
public class HomeworkOrder {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] t = new int[n];
int[] k = new int[n];
for (int i = 0; i < n; i++) {
t[i] = sc.nextInt();
k[i] = sc.nextInt();
}
List<Integer> order = divideAndConquer(n, t, k);
System.out.println("小明做作业的顺序为:" + order.toString());
}
public static List<Integer> divideAndConquer(int n, int[] t, int[] k) {
if (n == 0) {
return new ArrayList<>();
}
if (n == 1) {
List<Integer> list = new ArrayList<>();
list.add(0);
return list;
}
int minIndex = 0;
for (int i = 1; i < n; i++) {
if (t[i] < t[minIndex]) {
minIndex = i;
}
}
int[] t1 = new int[n - 1];
int[] k1 = new int[n - 1];
int j = 0;
for (int i = 0; i < n; i++) {
if (i != minIndex) {
t1[j] = t[i];
k1[j] = k[i];
j++;
}
}
List<Integer> order = divideAndConquer(n - 1, t1, k1);
order.add(minIndex);
int[] t2 = new int[n - 1];
int[] k2 = new int[n - 1];
j = 0;
for (int i = 0; i < n - 1; i++) {
t2[j] = t[order.get(i)];
k2[j] = k[order.get(i)];
j++;
}
int[] t3 = new int[n];
int[] k3 = new int[n];
t3[0] = t[minIndex];
k3[0] = k[minIndex];
for (int i = 1; i < n; i++) {
t3[i] = t2[i - 1];
k3[i] = k2[i - 1];
}
int[] sum = new int[n];
sum[0] = k3[0];
for (int i = 1; i < n; i++) {
sum[i] = sum[i - 1] + k3[i];
}
int minSum = Integer.MAX_VALUE;
int minIndex2 = -1;
for (int i = 0; i < n; i++) {
int s = sum[i] + (t3[i] - 1 - i) * k3[i];
if (s < minSum) {
minSum = s;
minIndex2 = i;
}
}
List<Integer> order2 = new ArrayList<>();
for (int i = 0; i < minIndex2; i++) {
order2.add(order.get(i));
}
order2.add(minIndex);
for (int i = minIndex2; i < n - 1; i++) {
order2.add(order.get(i));
}
return order2;
}
}
```
这个算法的思路是:首先找到最早截止时间的作业,将其放在最后做;然后递归处理剩下的作业,最后将最早截止时间的作业插入到其中一个位置,使得总扣分最小。
在这个算法中,我们使用了分治法对子问题进行处理,并利用了贪心选择策略和动态规划思想来求解问题。
阅读全文