题意:一条流水线上有M1个A机器,M2个B机器,以及N个待加工的零件。每个零件均需要经过A然后再经过B加工才能成行。每个机器加工一个零件的时间不一定是相同的,在输入中给出。求对所有零件进行A处理最短需要多久,加工完所有的零件最短需要多久?
解题思路:
- 参考NOCOW上的算法(http://www.nocow.cn/index.php/USACO/job)
- 设time[i][j] = k为第j个i种类机器(0为A,1为B)加工一个零件所需要的时间为k。delay[i][j] = k为第j个i种类机器(0为A,1为B)加工一个零件所需要等待的时间为k。cost[i][j] = k为i种类机器(0为A,1为B)加工第j个零件所需要的时间为k
- 对于A机器,首先将delay[0][0...M1-1]设为0,然后将所有N个零件一个一个加入其中,对每个零件j,取delay[0][0...M1-1] + times[0][0...M1-1] 中最小的值(假设为delay[0][k] + times[0][k]),并将delay[0][k]设为这个最小值,然后用cost[0][j] 来保存这个最小值
- 对于B机器,与3中的操作相同,用delay[1][0...M2-1],times[1][0...M2-1],cost[1][0...N-1]来替换其中的数组
- 通过3、4的操作我们得到了cost[0..1][0...N-1],然后取cost[0][0...N-1]中的最大值就是对所有零件进行A处理所需要的最短时间。cost[0][i] + cost[1][N-1-i](其中i取[0, N-1])中的最大值就是加工完所有零件所需要的最短时间
代码:
/*
ID: zc.rene1
LANG: C
PROG: job
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 99999
int N;
int M[2];
int times[2][30];
int delay[2][30];
int cost[2][1000];
int GetMin(int index)
{
int min = MAX;
int min_i = -1;
int i;
for (i=0; i<M[index]; i++)
{
if (delay[index][i] + times[index][i] < min)
{
min = delay[index][i] + times[index][i];
min_i = i;
}
}
delay[index][min_i] += times[index][min_i];
return min;
}
int main(void)
{
FILE *fin, *fout;
int i, j, temp, max = -1;
fin = fopen("job.in", "r");
fout = fopen("job.out", "w");
fscanf(fin, "%d %d %d", &N, &M[0], &M[1]);
for (i=0; i<M[0]; i++)
{
fscanf(fin, "%d", ×[0][i]);
}
for (i=0; i<M[1]; i++)
{
fscanf(fin, "%d", ×[1][i]);
}
memset(cost, 0, 2 * 1000 * sizeof(int));
memset(delay, 0, 2 * 30 * sizeof(int));
for (i=0; i<2; i++)
{
for (j=0; j<N; j++)
{
temp = GetMin(i);
cost[i][j] = temp;
}
}
for (i=0; i<N; i++)
{
if (cost[0][i] > max)
{
max = cost[0][i];
}
}
fprintf(fout, "%d ", max);
max = -1;
for (i=0; i<N; i++)
{
if (cost[0][i] + cost[1][N-i-1] > max)
{
max = cost[0][i] + cost[1][N-i-1];
}
}
fprintf(fout, "%d\n", max);
return 0;
}