IOI'96
A factory is running a production line that requires two operations to be performed on each job: first operation "A" then operation "B". Only a certain number of machines are capable of performing each operation.
Give the earliest time operation "A" can be completed for all N jobs provided that the jobs are available at time 0. Compute the minimal amount of time that is necessary to perform both operations (successively, of course) on all N jobs.
PROGRAM NAME: job
INPUT FORMAT
Line 1: | Three space-separated integers:
|
Line 2..etc: | M1 integers that are the job processing times of each type "A" machine (1..20) followed by M2 integers, the job processing times of each type "B" machine (1..20). |
SAMPLE INPUT (file job.in)
5 2 3 1 1 3 1 4
OUTPUT FORMAT
A single line containing two integers: the minimum time to perform all "A" tasks and the minimum time to perform all "B" tasks (which require "A" tasks, of course).SAMPLE OUTPUT (file job.out)
3 5
描述
一家工厂的流水线正在生产一种产品,这需要两种操作:操作A和操作B。每个操作只有一些机器能够完成。
上图显示了按照下述方式工作的流水线的组织形式。A型机器从输入库接受工件,对其施加操作A,得到的中间产品存放在缓冲库。B型机器从缓冲库接受中间产品,对其施加操作B,得到的最终产品存放在输出库。所有的机器平行并且独立地工作,每个库的容量没有限制。每台机器的工作效率可能不同,一台机器完成一次操作需要一定的时间。
给出每台机器完成一次操作的时间,计算完成A操作的时间总和的最小值,和完成B操作的时间总和的最小值。
[编辑]格式
PROGRAM NAME: job
INPUT FORMAT:
(file job.in)
第一行 三个用空格分开的整数:N,工件数量 (1<=N<=1000);M1,A型机器的数量 (1<=M1<=30);M2,B型机器的数量 (1<=M2<=30)。
第二行…等 M1个整数(表示A型机器完成一次操作的时间,1..20),接着是M2个整数(B型机器完成一次操作的时间,1..20)
OUTPUT FORMAT:
(file job.out)
只有一行。输出两个整数:完成所有A操作的时间总和的最小值,和完成所有B操作的时间总和的最小值(A操作必须在B操作之前完成)。
[编辑]SAMPLE INPUT
5 2 3 1 1 3 1 4
[编辑]SAMPLE OUTPUT
3 5
开始还很怕这种贪心的题目,感觉需要很多数学的证明。今天研究了一下,其实也并不是很难。
第一问很好解决。我们枚举每台机子的状态,寻找当前第i个产品放在哪里更快,并同时更新机器和商品的时间。等所有商品都枚举好后,选一个时间最大的即可。(当然是最后一个处理的商品)
后来的B机器也可以同上述方法过。但是我们会发现,B机器是直接和A机器相关的,于是我们不能光把B机器处理产品的最大时间输出。那么我们贪心地想一想:在A机器处理好后的产品中,速度快的一些我放在B机器中处理慢的地方。这样才能使时间更均衡。因此第二问的答案就是max(time1[i]+time2[n-i+1])(其中time1和time2分别是第i快的产品在A,B机器里操作的时间)
代码:
/*
PROG:job
ID:juan1973
LANG:C++
*/
#include<stdio.h>
using namespace std;
const int maxn1=1001;const int maxn2=31;const int INF=2000000000;
int na,nb,n,i,j,min,ans,k;
int time1[maxn1],time2[maxn1],timea[maxn2],timeb[maxn2],a[maxn2],b[maxn2];
int main()
{
freopen("job.in","r",stdin);
freopen("job.out","w",stdout);
scanf("%ld%ld%ld",&n,&na,&nb);
for (i=1;i<=na;i++) scanf("%ld",&a[i]);
for (i=1;i<=nb;i++) scanf("%ld",&b[i]);
for (i=1;i<=n;i++)
{
min=INF;
for (j=1;j<=na;j++)
if (timea[j]+a[j]<min) {min=timea[j]+a[j];k=j;}
timea[k]=time1[i]=min;
}
printf("%ld ",min);
for (i=1;i<=n;i++)
{
min=INF;
for (j=1;j<=nb;j++)
if (timeb[j]+b[j]<min) {min=timeb[j]+b[j];k=j;}
timeb[k]=time2[i]=min;
}
ans=0;
for (i=1;i<=n;i++)
if (time1[i]+time2[n-i+1]>ans) ans=time1[i]+time2[n-i+1];
printf("%ld\n",ans);
//scanf("%ld",&n,&na,&nb);
return 0;
}