题目链接:
思路:
对于每个work,寻找当前是哪个工序,在哪个机器上完成,耗时 t 是多少,以及该工件上一工序完成时间,然后从这个时间点开始,寻找该机器连续 t 的空闲时间。最后统计最晚的工序完成时间即可(注意不一定是最后一道工序的完成时间)。
学到的一些写代码技巧
- 代码分块,input和solve分开,临时变量的准备和处理逻辑分开。
- 变量命名:同一类型的变量可以用同一前缀表示,如whi(whch_i)表示当前工件,whs(which_step)表示当前工序。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 21;
int m, n; //机器/工序数,工件数
int work[maxn*maxn]; //安排顺序
struct node{int id, tme;}; //每个工序使用机器号,用时
node a[maxn][maxn]; // a[i][j]表示工件i,工序j
int mac[maxn][10000]; //机器是否空闲
int step[maxn]; //工件工序进行到第几工序
int last[maxn]; //每个工件上一步骤结束时间
int ans = 0; //最终用时
int main(){
//input
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> m >> n; int w=m*n; //任务数
for(int i=1; i<=w; i++) cin>>work[i]; //任务列表
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
cin>>a[i][j].id; //第i个工件,第j个工序的机器号
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
cin>>a[i][j].tme; //第i个工件,第j个工序的用时
//solve
for(int i=1; i<=w; i++){
int whi = work[i]; //工件
int whs = ++step[whi]; //工序
int ma = a[whi][whs].id; //机器
int t = a[whi][whs].tme; //耗时
int cnt=0, end; //时间块计数,结束时间
for(int j=last[whi]+1;; j++){
if(!mac[ma][j]) cnt++; //当前空闲,累积时间
else cnt = 0; //当前忙,时间清零
if(cnt==t) {end=j; break;}
}
for(int j=end-t+1; j<=end; j++) mac[ma][j] = 1; //记录繁忙
last[whi] = end; //记录结束时间
ans = max(ans, end);
}
cout<<ans;
}