【题目】LuoguP1065
准备机试,做两道题复健(这事我是不是干了好多次了)。
https://www.luogu.com.cn/problem/P1065
题意是有n个工件,每个工件有m道工序,每个工件的每道工序有其用时,同时对应一台机器,机器总共也有m台。每台机器同时只能处理一个工序。现给出工件的工序顺序,问尽可能靠前安排,所用的时间。
一种显然的做法是把时间像桶一样存起来,每安排一个工序就把一个区间格式化为占用。然后每次从开头开始查找。
但是要我说,这么做能过是因为数据不给力。比如,如果某工序需要2^31-1时间的话就不行了。
注意到工件和工序数量相对较少,所以可以用存区间+排序的方法做。具体思路是,对于每台机器创建一个区间列表来表示占用了的区间,添加新区间时就查找区间之间的间隔是否有足够大的,如果有就靠前插入。另外由于同一个工件的工序有前后之分,所以还需要一个数组来记录上一个工序的最后完成时间,和查找范围的左侧取最值。
一个小trick是存储区间的时候在头和尾多存储两个,头的右边界是0,尾的左边界是无穷,这样不需要额外的边界判断逻辑。
AC代码:
#include <iostream> #include <cstdio> #include <utility> #include <algorithm> #define fr first #define se second using namespace std; const int MAXN = 22;//product const int MAXM = 22;//process pair<int,int> info[MAXN][MAXM];//machine, time use int order[MAXN*MAXM]; int m,n; int lastpos[MAXN]; int step[MAXN]; pair<int,int> bsy[MAXM][MAXN*MAXM]; int cnt[MAXM]; int ntime; bool cmp(pair<int,int> a, pair<int,int> b){ return a.fr < b.fr; } int _max(int a,int b){ return a>b?a:b; } int main(){ //freopen("./p1065.in","r",stdin); //freopen("./p1065.out","w",stdout); cin>>m>>n; for(int i = 1; i <= n*m ; i++) cin>>order[i]; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m ; j++) cin>>info[i][j].first; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m ; j++) cin>>info[i][j].second; for(int i = 1; i <= m ; i++){ bsy[i][1].fr = 0x7fffff; cnt[i] = 1; } int mx = 0; for(int iii = 1; iii <= n*m ; iii++){ int nowpro = order[iii]; int nowstep = step[nowpro]+1; int nowmac = info[nowpro][nowstep].fr; int nowtime = info[nowpro][nowstep].se; for(int i = 1; i <= cnt[nowmac]; i++){ int rig = _max(bsy[nowmac][i-1].se, lastpos[nowpro]); if(bsy[nowmac][i].fr - rig - 1 >= nowtime){ bsy[nowmac][cnt[nowmac]].fr = rig + 1; bsy[nowmac][cnt[nowmac]].se = rig + nowtime; lastpos[nowpro] = bsy[nowmac][cnt[nowmac]].se; //printf("新的%d的最后位置为%d \n",nowpro, lastpos[nowpro]); if(bsy[nowmac][cnt[nowmac]].se > mx) mx = bsy[nowmac][cnt[nowmac]].se; //printf("add:machine:%d,product:%d,count:%d,%d-%d\n",nowmac,nowpro,cnt[nowmac],bsy[nowmac][cnt[nowmac]].fr,bsy[nowmac][cnt[nowmac]].se); bsy[nowmac][++cnt[nowmac]].fr = 0x7fffff; step[nowpro] ++; break; } } sort(bsy[nowmac]+1, bsy[nowmac] + cnt[nowmac], cmp); } cout<<mx<<endl; return 0; }