**题目描述**
有 $n$ 份工作要分配给 $n$ 个人来完成,每个人完成一份。第 $i$ 个人完成第 $k$ 份工作所用的时间为一个正整数 $t_{i,k}$,其中 $1 \leq i, k \leq n$。试确定一个分配方案,使得完成这 $n$ 份工作的时间总和最小。
-
+
输入包含 $n + 1$ 行。
-
+
第 1 行为一个正整数 $n$。
-
+
第 2 行到第 $n + 1$ 行中每行都包含 $n$ 个正整数,形成了一个 $n \times n$ 的矩阵。在该矩阵中,第 $i$ 行第 $k$ 列元素 $t_{i,k}$ 表示第 $i$ 个人完成第 $k$ 件工作所要用的时间。
-
+
输出包含一个正整数,表示所有分配方案中最小的时间总和。
-
+
限制范围:
-
+
$1 \leq n \leq 15$
-
+
$1 \leq t_{i,k} \leq 10^4$
-
+
输入样例:
-
+
```text
5
9 2 9 1 9
8 8 1 8 4
9 1 7 8 9
```
-
+
输出样例:
-
+
```text
5
```
检查工作分配,其实就是判断取得可行解时的二维数组的第一维下标各不相同并且第二维下标各不相同。而我们是要得到完成这 $n$ 份工作的最小时间总和,即可行解中时间总和最小的一个,故需要再定义一个全局变量 `cost_time_total_min` 表示目前找到的解中最小的时间总和,初始 `cost_time_total_min` 为 `time[i][i]` 之和,即对角线工作时间相加之和。在所有人分配完工作时,比较 `count` 与 `cost_time_total_min` 的大小,如果 `count` 小于 `cost_time_total_min` ,说明找到了一个最优解,此时就把 `count` 赋给 `cost_time_total_min` 。
-但考虑到算法的复杂度,这里还有一个剪枝优化的工作可以做。就是在每次计算局部费用变量 $count$ 的值时,如果判断 $count$ 已经大于 `cost_time_total_min` ,就没必要再往下分配了,因为这时得到的解必然不是最优解。
+但考虑到算法的效率,这里还有一个剪枝优化的工作可以做。就是在每次计算局部费用变量 `count` 的值时,如果判断 `count` 已经大于 `cost_time_total_min` ,就没必要再往下分配了,因为这时得到的解必然不是最优解。
#### 经典例题代码
is_working[j] = 1;
// 工作交给第 i + 1 个人
work(i + 1, count + time[i][j], n);
- // 在一轮迭代完成之后,返回到上一个人,要对此次的工作进行重新分配,将
- // is_working[j] 重设为 0
+ // 在一轮迭代完成之后,返回到上一个人,要对此次的工作进行重新分配
+ // 将 is_working[j] 重设为 0
is_working[j] = 0;
}
}