多机调度问题
题目描述
设有n个独立的作业{1, 2, …, n},由m台相同的机器{M1, M2, …, Mm}进行加工处理,作业i所需的处理时间为 t i(1≤i≤n),每个作业均可在任何一台机器上加工处理,但不可间断、拆分。多机调度问题要求给出一种作业调度方案,使所给的n个作业在尽可能短(注意不一定是最短)的时间内由m台机器加工处理完成。
输入描述
两行,第一行为两个整数n,m。(1<=m<=50,m<=n<=100)。第二行n个整数,代表n个任务的时间。
输出描述
一个整数,最小执行时间。
用例输入 1
7 3
2 14 4 16 6 5 3
用例输出 1
17
思路
很遗憾,多机调度问题目前为止依然是一个无法解决的问题(无法通过一个高效的算法得到最优解)。所以,目前只能使用贪心策略得到一个近似优解,而非最优解。同时,本题题目要求也强调不需给出最优解。所以本题采用贪心策略:从时间最长的任务开始分配,每次分配给最先空闲的机器。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int n, m;
cin >> n >> m;
vector<int> sum(m, 0);
vector<int> a(n);
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(a.begin(), a.end()); // 转为升序
reverse(a.begin(), a.end()); // 转为降序
if (n <= m)
{
cout << a[0];
return 0;
}
for (int i = 0; i < m; i++)
{
sum[i] += a[i]; // 每个机器当前已处理作业时间
}
for (int i = m; i < n; i++)
{
int pos = -1; // 最先空闲的机器的位置
int minn = INT_MAX;
for (int i = 0; i < m; i++)
{
if (sum[i] < minn)
{
minn = sum[i];
pos = i;
}
}
sum[pos] += a[i];
}
int maxn = 0;
for (int i = 0; i < m; i++)
{
maxn = max(maxn, sum[i]); // 最后完成的作业的机器所花的时间即为最小执行时间
}
cout << maxn << '\n';
return 0;
}