有若干个任务需要在一台机器上运行。
它们之间没有依赖关系,因此可以被按照任意顺序执行。
该机器有两个 CPU 和一个 GPU。
对于每个任务,你可以为它分配不同的硬件资源:
- 在单个 CPU 上运行。
- 在两个 CPU 上同时运行。
- 在单个 CPU 和 GPU 上同时运行。
- 在两个 CPU 和 GPU 上同时运行。
一个任务开始执行以后,将会独占它所用到的所有硬件资源,不得中断,直到执行结束为止。
第 ii 个任务用单个 CPU,两个 CPU,单个 CPU 加 GPU,两个 CPU 加 GPU 运行所消耗的时间分别为 ai,bi,ci 和 di。
现在需要你计算出至少需要花多少时间可以把所有给定的任务完成。
输入格式
输入的第一行只有一个正整数 n,是总共需要执行的任务个数。
接下来的 n 行每行有四个正整数 ai,bi,ci,di,以空格隔开。
输出格式
输出只有一个整数,即完成给定的所有任务所需的最少时间。
数据范围
1≤n≤40,
1≤ai,bi,ci,di≤10
输入样例:
3 4 4 2 2 7 4 7 4 3 3 3 3
输出样例:
7
样例解释
有很多种调度方案可以在 7 个时间单位里完成给定的三个任务,以下是其中的一种方案:
同时运行第一个任务(单 CPU 加上 GPU)和第三个任务(单 CPU),它们分别在时刻 2 和时刻 3 完成。
在时刻 3 开始双 CPU 运行任务 2,在时刻 7 完成。
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 50, M = 210, INF = 0x3f3f3f3f;
int n;
int f[2][M][M][M];
int c[N][3];
int main()
{
cin >> n;
int m = 0, m2 = 0;
for (int i = 1; i <= n; i ++)
{
int x, y, z, t;
cin >> x >> y >> z >> t;
c[i][0] = x, c[i][1] = z, c[i][2] = min(y, t);
m += x;
if (i % 2) m2 += x;
}
m = max(m2, m - m2);
memset(f, 0x3f, sizeof f);
f[0][0][0][0] = 0;
for (int u = 1; u <= n; u ++)
for (int i = 0; i <= m; i ++)
for (int j = i; j <= m; j ++)
for (int k = 0; k <= j; k ++) //k<=j (GPU不能单独使用)
{
int &v = f[u & 1][i][j][k];
int x = c[u][0], y = c[u][1], z = c[u][2], t = u - 1 & 1;
v = f[t][i][j][k] + z; //模式3
if (i >= x) v = min(v, f[t][min(i - x, j)][max(i - x, j)][k]); //模式1
if (j >= x) v = min(v, f[t][min(j - x, i)][max(j - x, i)][k]); //模式1
if (i >= y && k >= y) v = min(v, f[t][i - y][j][k - y]); //模式2
if (j >= y && k >= y) v = min(v, f[t][i][j - y][k - y]); //模式2
}
int res = INF;
for (int i = 0; i <= m; i ++)
for (int j = i; j <= m; j ++)
for (int k = 0; k <= j; k ++)
res = min(res, f[n & 1][i][j][k] + max(max(i, j), k));
cout << res;
return 0;
}