记录编号 287683 评测结果 AAAAAAAAAA
题目名称 [NOIP 2006]作业调度方案 最终得分 100
用户昵称 GravatarTwist Fate 是否通过 通过
代码语言 C++ 运行时间 0.015 s
提交时间 2016-08-02 10:31:26 内存使用 1.82 MiB
显示代码纯文本
// NOIP 2006 第三题
//这题题目太绕了,(#‵′)靠。。
//所以讲讲题目大意,理理思路
//(1)对同一个工件,每道工序必须在它前面的工序完成后才能开始;
//(2)同一时刻每一台机器至多只能加工一个工件。
//(3)还要注意,“安排顺序”只要求按照给定的顺序安排每个操作。不一定是各机器上的实际操作顺序。在具体实施时,有可能排在后面的某个操作比前面的某个操作先完成。 
//这三句话是重点,比如1-1,1-2,2-1,3-1,3-2,2-2 
//也就是说在所有第一工序中,1号肯定要the first blood,
//在所有第二工序中,一号还是一血。。。。所以。。。
//就不停更新代表机器的数组,直到处理了n*m个工序为止 
//至于主程序,就是纯模拟O__O "…
//O(≧口≦)O好难啊(=@__@=)。。
//NOIP2006作业调度
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; 
const int  maxn=20;
int d[maxn*maxn+1];
int id[maxn+1][maxn+1],t[maxn+1][maxn+1];
int f[maxn][maxn*1000+1];
int c[maxn+1],p[maxn+1];
int k=0,now=0,temp=0,j,i;
bool flag;
int main(){
	freopen("jsp.in","r",stdin);
	freopen("jsp.out","w",stdout);
	int n,m;
	scanf("%d%d",&m,&n);//m表示机器数,n表示工件数 
	for(i=1;i<=n*m;i++)
		scanf("%d",&d[i]);
	for(i=1;i<=n;i++)	
		for(j=1;j<=m;j++)
			scanf("%d",&id[i][j]);
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			scanf("%d",&t[i][j]);
		memset(f,true,sizeof(f));
	for(i=1;i<=n*m;i++){
		now=d[i];
		c[now]++;//更新工作序号
		k=p[now]+1;//纪录起点
		do{
     while(!f[id[now][c[now]]][k]) k++; //跳过无法工作区域
     flag=true;
     for(j=k;j<=k+t[now][c[now]]-1;j++) //检验是否有足够时间
       if(!f[id[now][c[now]]][j])
       {
          flag=false;
          temp=j;//记录停止时间
          break;
       }
     if(flag)
     {
       for(j=k;j<=k+t[now][c[now]]-1;j++) //将当前工作写入工作轴中
          f[id[now][c[now]]][j]=false;
       p[now]=k+t[now][c[now]]-1; //更新起点
       break;
    }
     k=temp; //假如没有足够时间则从停止时间重新开始
   }while(true);
}
	k=-1000000;
	for(i=1;i<=maxn;i++)
		k=max(k,p[i]);
	printf("%d",k);
	return 0;
}