Bootstrap

27. 高效的任务规划

题目描述

你有 n 台机器,编号为 1~n,每台都需要完成一项工作,机器经过配置后都能完成独 立完成一项工作。 。假设第 i 台机器你需要花 B 分钟进行设置,然后开始运行,J 分钟后完成任务。 。现在,你需要选择布置工作的顺序,使得用最短的时间完成所有工作。 。注意,不能同时对两台进行配置,但配置完成的机器们可以同时执行他们各自的工作.

输入描述

第一行输入代表总共有 M 组任务数据 (1<M<=10)。 。每组数第一行为一个整数指定机器的数量 N (0<N<=1000)。 随后的 N 行每行两个整数,第一个表示 B (0<=B<=10000),第二个表示 J (0<=J<=10000)

每组数据连续输入,不会用空行分隔。各组任务单独计时。

输出描述

对于每组任务,输出最短完成时间,且每组的结果独占一行。例如,两组任务就应该有

两行输出

用例

一、问题分析

首先读题,仔细看描述中的内容,发现需求是

1.你有n台机器,编号为1~n,每台都需要完成一项工作,机器经过配置后都能独立完成一项工作。

2.假设第i台机器你需要花B分钟进行设置,然后开始运行,J分钟后完成任务

3.现在,你需要选择布置工作的顺序,使得用最短的时间完成所有工作

4.注意,不能同时对两台进行配置,但配置完成的机器们可以同时执行它们各自的工作

5.输入描述:第一行输入代表总共有M组任务数据(M大于1小于等于10)

每组数第一行为一个整数指定机器的数量N(N大于0小于等于1000)

随后的N行每行两个整数,第一个表示B(B大于等于0小于等于10000)

第二个表示J(J大于等于0小于等于10000)

每组数据连续输入,不会用空行分隔。各组任务单独计时。

6.输出描述:对于每组任务,输出最短完成时间,且每组的结果独占一行。

二、解题思路

1.第一感觉是应该先配置运行时间长的,因为在运行时间长的机器运行的过程中我们可以配置其他的机器,这样的话时间起到一个叠加的效果

2.比如一台机器配置时间是1分钟,运行时间是1分钟,一台机器配置时间是1分钟,运行时间是2分钟,我们将第一台机器称为机器A,第二台称为机器B,现在是机器B的运行时间比较长

如果我们先配置机器B,那么配置时间是1分钟,然后开始运行2分钟,同时我们配置机器A,配置时间是1分钟,此时机器B刚刚运行1分钟,还需要运行1分钟,而机器A刚好需要运行1分钟。

所以我们总共的时间是配置机器B的1分钟+配置机器A的1分钟+等待运行的1分钟一共是3分钟。

3.因为我们希望尽早完成工作,所以我们一定是不停的配置,然后最后的等待时间希望是最短的

如果我们先配置运行时间短的机器A的话,配置机器A的时间是1分钟,然后机器A开始运行,然后配置机器B,配置时间是1分钟,配置完成的时候机器A已经停止运行,然后还需要等待机器B运行2分钟,所以一共的时间是配置机器A的1分钟+配置机器B的1分钟+等待运行的2分钟一共是4分钟。

4.再比如,一个机器A配置时间是2分钟,运行时间是1分钟,机器B配置时间是2分钟,运行时间是2分钟,我们一样是先配置运行时间比较长的机器B总时间比较短

先配置机器B,配置时间2分钟+配置机器A的时间2分钟+机器A运行的时间1分钟 = 5分钟

如果先配置机器A,配置时间2分钟,配置机器B的时间2分钟+机器B运行时间2分钟 = 6分钟

5.那么如果运行时间相等的情况下呢?比如机器A配置时间是1分钟,运行时间是1分钟,机器B配置时间是2分钟,运行时间是1分钟。

如果先配置机器A,1分钟然后配置机器B,2分钟(此时机器A已经运行完毕),之后在等待机器B运行1分钟,一共的时间是1+2+1=4分钟

如果先配置机器B,配置2分钟,然后配置机器A,1分钟(此时机器B已经运行完毕),之后在等待机器A运行1分钟,总共的时间是2+1+1=4分钟

6.以上是运行时间相等,但是配置时间比较长的例子,如果是运行时间相等,但是配置时间比运行时间短呢?比如机器A配置时间1分钟,运行时间3分钟,机器B配置时间2分钟,运行时间3分钟

这个时候我们发现不管是先配置机器A还是机器B我们需要的总时间总是1+2+3=6分钟

7.如果我们机器A配置时间3分钟,运行时间1分钟,机器B配置时间5分钟,运行时间1分钟呢?

此时不管我们先配置机器A还是先配置机器B我们的总时间都是3+5+1=9分钟

8.如果我们机器A配置时间3分钟,运行时间是8分钟,机器B配置时间是5分钟,运行时间是4分钟呢?

如果我们还是选择先配置运行时间长的机器A的话,我们配置机器A需要3分钟,然后配置机器B,5分钟,配置好机器B我们机器A运行的剩余时间是3分钟,此时机器B需要的运行时间是4分钟,所以在机器B运行到第三分钟的时候机器A停止运行然后机器B还需要运行1分钟,总时间是3+5+4=12分钟

如果先配置运行时间短的机器B的话,那么我们配置机器B的时间是5分钟,然后配置机器A,3分钟,配置完机器A,机器B的运行时间也只剩下1分钟了,我们还需要等待机器A运行的8分钟,总时间是5+3+8=16分钟

9.先配置运行时间长的机器是因为我们的配置时间和运行时间叠加在一起的时间越长,那么我们节约的时间就越长,

假设我们只能配置并运行一台机器,那么无论我们先配置那台最后的时间都是一样的,而我们能够在一台机器运行的时候配置另外一台机器就是我们可以节省时间的原因,所以一定是在一台机器运行的时候配置另外一台机器才更节省时间,所以我们采取先配置运行时间较长的机器的方法来解答这个题目。

三、具体步骤

使用的语言是C

#include <stdlib.h>
#include <stdio.h>
int compare(const void* a, const void* b) {
    int (*arr_a)[2] = (int (*)[2])a;
    int (*arr_b)[2] = (int (*)[2])b;
    return (*arr_b)[1] - (*arr_a)[1];
}

void printBJ(int BJ[][2], int size) {
    for(int i = 0; i < size; i++) {
        printf("%d %d\n", BJ[i][0], BJ[i][1]);
    }
}
int main() {
    // 定义一个整数M代表有M组任务
    int M;
    scanf("%d", &M);
    for(int i = 0; i < M; i++) {
        // 定义一个整数N代表有N台机器
        int N;
        scanf("%d", &N);
        // 定义一个整数数组BJ[N][2],其中BJ[N][0]代表配置时间,其中BJ[N][1]代表运行时间
        int BJ[N][2];
        for(int j = 0; j < N; j++) {
            scanf("%d %d", &BJ[j][0], &BJ[j][1]);
        }
        // 之后我们对BJ进行排序,运行时间较长的排在前面
        qsort(BJ, N, sizeof(BJ[0]), compare);
        // printBJ(BJ, N);
        // 我们从BJ中运行时间最长的开始配置,
        int total = 0; // 总时间
        int running = 0; // 剩余的运行时间
        for(int j = 0; j < N; j++) {
            // 首先我们的配置时间是必须要等待的,所以直接加入总时间中,
            total += BJ[j][0];
            if(running > BJ[j][0]) {
                // 然后如果我们剩余的运行时间多于配置一台机器的时间,我们剩余的运行时间需要和这台机器的运行时间做一个比较,然后时间比较长的成为我们新的运行时间
                running -= BJ[j][0];
                if(running < BJ[j][1]) {
                    // 如果剩余运行时间多于这台时间的运行时间,我们还是等待这台机器,否则我们等待新机器的运行时间
                    running = BJ[j][1];
                }
            } else {
                running = BJ[j][1];
            }
        }
        total += running;
        printf("%d\n", total);
    }
    return 0;
}

;