题目描述
假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti。试设计一个算法找出完成这n个任务的最佳调度,使得完成全部任务的时间最早。对任意给定的整数n和k,以及完成任务i需要的时间为ti,1≤i≤n。编程计算完成这n个任务的最佳调度。
输入格式
第一行,两个正整数n和k。
第二行,n个正整数,是完成n个任务需要的时间。
输出格式
一行,一个整数,完成全部任务的最早时间。
输入样例
7 3
2 14 4 16 6 5 3
输出样例
17
题解
容易想到,我们按照顺序对每一个工作放在每一个机器上的情况进行搜索。但是显然会tle,那就需要我们进行剪枝。
首先,我们设当前情况下的时间为$t$,当前已知的最优解为$ans$,则当$t geqslant ans$时,我们可以直接return。
这个时候我们想,为了尽可能多剪,我们可以对每个工作进行降序排序,然后从时间长的开始搜。
其实还有一个剪枝。假设机器$i$和机器$j$当前运作的时间相同,那实际上我们只用搜当前工作放在机器$i$上的情况就好了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <algorithm> #define MAX_N (20 + 5) #define MAX_M (20 + 5) using namespace std; int n, m; int a[MAX_N]; int b[MAX_M]; int ans = 0x7f7f7f7f; void DFS(int x, int t) { if(t >= ans) return; if(!x) { ans = t; return; } bool c[1000] = {0}; for(register int i = 1; i <= m; ++i) { if(c[b[i]]) continue; c[b[i]] = true; b[i] += a[x]; DFS(x - 1, max(t, b[i])); b[i] -= a[x]; } return; } int main() { cin >> n >> m; for(register int i = 1; i <= n; ++i) { cin >> a[i]; } sort(a + 1, a + n + 1); DFS(n, 0); cout << ans; return 0; }