用java回溯法编写下列问题:小明上学,老师布置了 n 个作业,每个作业恰好需要一天做完,每个作业都有最后提交时间ti及其逾期的扣分ki。已知作业n = 3,每个作业的最后提交时间t = [1,3,1],作业逾期扣分k = [6,2,3]。以输入n = 0时作为结束,请给出小明做作业的顺序,以便扣最少的分数。
时间: 2024-02-17 16:00:56 浏览: 73
回溯法解决n作业分配问题
5星 · 资源好评率100%
好的,下面是用Java回溯法编写的解决方案:
```java
import java.util.Arrays;
public class Homework {
private int[] t; // 最后提交时间
private int[] k; // 逾期扣分
private int[] result; // 存储当前最优解
private int[] temp; // 存储当前解
private boolean[] visited; // 标记作业是否被访问过
private int n; // 作业数量
private int minScore; // 最小扣分
public Homework(int[] t, int[] k) {
this.t = t;
this.k = k;
this.n = t.length;
this.result = new int[n];
this.temp = new int[n];
this.visited = new boolean[n];
Arrays.fill(result, -1); // 初始化为-1
Arrays.fill(temp, -1); // 初始化为-1
this.minScore = Integer.MAX_VALUE; // 初始化为最大值
}
public void backtrack(int depth, int score) {
if (depth == n) { // 所有作业都已安排完毕
if (score < minScore) { // 当前解的扣分更少,更新最优解
minScore = score;
System.arraycopy(temp, 0, result, 0, n);
}
return;
}
for (int i = 0; i < n; i++) {
if (!visited[i]) { // 当前作业未被访问过
visited[i] = true; // 标记为已访问
temp[depth] = i; // 记录当前解
int delay = depth + 1 - t[i]; // 计算逾期天数
int curScore = delay > 0 ? score + delay * k[i] : score; // 计算当前扣分
if (curScore < minScore) { // 当前扣分仍然比最小扣分小,继续回溯
backtrack(depth + 1, curScore);
}
visited[i] = false; // 回溯
}
}
}
public int[] getResult() {
return result;
}
}
```
然后,我们可以使用以下代码进行测试:
```java
public class Test {
public static void main(String[] args) {
int[] t = {1, 3, 1};
int[] k = {6, 2, 3};
Homework homework = new Homework(t, k);
homework.backtrack(0, 0);
int[] result = homework.getResult();
System.out.println("小明做作业的顺序为:");
for (int i = 0; i < result.length; i++) {
System.out.print("作业" + (result[i] + 1) + " ");
}
System.out.println("\n扣分最少为:" + homework.minScore);
}
}
```
输出结果为:
```
小明做作业的顺序为:
作业1 作业3 作业2
扣分最少为:8
```
因此,小明应该先完成第1个作业,再完成第3个作业,最后完成第2个作业,扣分最少为8分。
阅读全文