3201. 任务调度

有若干个任务需要在一台机器上运行。

它们之间没有依赖关系,因此可以被按照任意顺序执行。

该机器有两个 CPU 和一个 GPU。

对于每个任务,你可以为它分配不同的硬件资源:

  1. 在单个 CPU 上运行。
  2. 在两个 CPU 上同时运行。
  3. 在单个 CPU 和 GPU 上同时运行。
  4. 在两个 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;
}
相关推荐
哭泣的眼泪4081 小时前
解析粗糙度仪在工业制造及材料科学和建筑工程领域的重要性
python·算法·django·virtualenv·pygame
Microsoft Word2 小时前
c++基础语法
开发语言·c++·算法
天才在此2 小时前
汽车加油行驶问题-动态规划算法(已在洛谷AC)
算法·动态规划
莫叫石榴姐3 小时前
数据科学与SQL:组距分组分析 | 区间分布问题
大数据·人工智能·sql·深度学习·算法·机器学习·数据挖掘
茶猫_4 小时前
力扣面试题 - 25 二进制数转字符串
c语言·算法·leetcode·职场和发展
肥猪猪爸6 小时前
使用卡尔曼滤波器估计pybullet中的机器人位置
数据结构·人工智能·python·算法·机器人·卡尔曼滤波·pybullet
readmancynn6 小时前
二分基本实现
数据结构·算法
萝卜兽编程6 小时前
优先级队列
c++·算法
盼海6 小时前
排序算法(四)--快速排序
数据结构·算法·排序算法
一直学习永不止步6 小时前
LeetCode题练习与总结:最长回文串--409
java·数据结构·算法·leetcode·字符串·贪心·哈希表