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


// Problem: P1065 [NOIP2006 提高组] 作业调度方案
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1065
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// User: Pannnn

#include 

using namespace std;

bool check(vector &timeLine, int startTime, int timeLong) {
    // 从某个时间点开始的timeLong时间线内都没有被占用,返回true,否则返回1
    for (int i = startTime; i < startTime + timeLong; ++i) {
        if (timeLine[i] == 1) {
            return false;
        }
    }
    return true;
}

void put(vector &timeLine, int startTime, int timeLong) {
    for (int i = startTime; i < startTime + timeLong; ++i) {
        timeLine[i] = 1;
    }
}

int run(vector opeQue, vector> opeInfo, vector> opeTime,
    int m, int n) {
    
    vector runState(n);    // n个工件下一步执行到第几个步骤,[0, m)
    vector runTime(n);     // n个工件下一个步骤最早的开始时间
    // 机器的时间点,点为1表示被占用
    vector> machine(m, vector(100010));
    
    for (int i = 0; i < m * n; ++i) {
        int id = opeQue[i];    // 当前操作工件号
        int op = runState[id];  // 当前工件要执行步骤号
        ++runState[id];         // 更新工件步骤号
        
        int machineId = opeInfo[id][op];   // 工件当前步骤需要在此机器上运行
        int machineTime = opeTime[id][op]; // 此步骤需要时间
        int startTime = runTime[id];
        
        // 遍历机器时间线
        for (int j = startTime; j < machine[machineId].size(); ++j) {
            // 以j开始的时间是否有machineTime的空闲
            if (check(machine[machineId], j, machineTime)) {
                // 占用此时间
                put(machine[machineId], j, machineTime);
                runTime[id] = j + machineTime; // 更新下一个步骤最早的开始时间
                break;
            }
        }
    }
    int time = 0;
    for (int i = 0; i < runTime.size(); ++i) {
        time = max(time, runTime[i]);
    }
    return time;
}

int main() {
    int m, n;
    cin >> m >> n;
    
    vector opeQue;
    int t;
    for (int i = 0; i < m * n; ++i) {
        cin >> t;
        // 工件下标从0开始,-1存储
        opeQue.push_back(t - 1);
    }
    
    vector> opeInfo;
    vector> opeTime;
    
    for (int i = 0; i < n; ++i) {
        // 工件的机器顺序
        vector tInfo;
        for (int j = 0; j < m; ++j) {
            cin >> t;
            // 机器下标从0开始,-1存储
            tInfo.push_back(t - 1);
        }
        opeInfo.push_back(tInfo);
    }
    
    for (int i = 0; i < n; ++i) {
        // 工件的步骤耗时
        vector tInfo;
        for (int j = 0; j < m; ++j) {
            cin >> t;
            tInfo.push_back(t);
        }
        opeTime.push_back(tInfo);
    }
    
    cout << run(opeQue, opeInfo, opeTime, m, n) << endl;
    return 0;
}

相关