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;
}
相关推荐
ZZZ_O^O17 分钟前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
CV-King40 分钟前
opencv实战项目(三十):使用傅里叶变换进行图像边缘检测
人工智能·opencv·算法·计算机视觉
代码雕刻家1 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
雨中rain1 小时前
算法 | 位运算(哈希思想)
算法
Kalika0-03 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
sp_fyf_20243 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
我是哈哈hh5 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
Tisfy5 小时前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java5 小时前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode
robin_suli5 小时前
滑动窗口->dd爱框框
算法