[洛谷] P1065 [NOIP2006 提高组] 作业调度方案

image
image


点击查看代码
#include<bits/stdc++.h>

using namespace std;
const int N = 1e6 + 10;
int m, n, ans = 0;
int lists[500];
int steps[25];
int machine[25][N];
int last_time[25];
struct information {
    int id;
    int cost;
}a[25][25];
int main()
{
    cin >> m >> n;
    for (int i = 1; i <= m * n; i++)
        cin >> lists[i];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> a[i][j].id;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> a[i][j].cost;
    for (int i = 1; i <= m * n; i++) {
        int now = lists[i];
        steps[now]++;
        int id = a[now][steps[now]].id, cost = a[now][steps[now]].cost;
        int s = 0;
        for (int j = last_time[now] + 1; ; j++) {
            if (machine[id][j] == 0)    s++;
            else    s = 0;
            if (s == cost) {
                for (int k = j - cost + 1; k <= j; k++)
                    machine[id][k] = 1;
                if (ans < j)    ans = j;
                last_time[now] = j;
                break;
            }
        }
    }
    cout << ans;
    return 0;
}
------------ ------------

此题的标签为模拟,我们可以定义一些数组和结构体来储存题干的信息:lists[i] 用来表示安排顺序,steps[i] 表示工件i所处的工序数,machine[i][j] 表示第i个机器目前处在时间轴上的第j个时间,last_time[i] 表示第i个工件现在处在时间轴上的时间(之后我会具体解释),a[i][j].id 表示第 i 个工件的第 j 个工序的机器号,a[i][j].cost 表示第 i 个工件的第 j 个工序的加工时间。在进行模拟时,有 3 个条件需要满足:(1)要按照题干的安排顺序进行加工(2)机器的加工时间在时间轴上是从 0 开始向右走(3)每个工件的各个工序在时间轴上对应的时间也是没有重叠部分的,我们之前定义的 last_time[i] 就是为了表示第i个工件目前所处的时间,当下一次轮到工件i的工序时,要从 last_time[i] 开始,这样才能保证在时间上没有冲突。

来分析一下程序的主要部分,用 now 存储 lists[i] 当前对应的工件,steps[now] ++ 后即为此时工件所对应的工序号,使用 id 和 cost 来存储当前的机器号和加工时间,定义一个变量 s ,以便后续判断何时能够加工,循环变量 j 从 last_time[now] + 1 开始(为了满足条件3),进行循环,直到找到能够满足加工时间的时间段,记录下完成目前这项工序的时间j,做以下操作:(1)将满足的这段时间在机器上标记为占用,也就是 machine[id][k] = 1(2)如果此时的时间已经超过了之前的总时间 ans ,就执行 ans = j(因为我们要找的是满足题干所有情况的最短时间,相当于是求交集)(3)将工件 now 的 last_time[now] 更新为 j(4)退出循环

最后找到的ans就是满足条件的最短加工时间

posted @ 2022-04-10 15:24  wKingYu  阅读(118)  评论(0编辑  收藏  举报