现在的位置: 首页 > 综合 > 正文

usaco training 4.2.3 Job Processing 题解

2014年04月05日 ⁄ 综合 ⁄ 共 3056字 ⁄ 字号 评论关闭

Job Processing题解
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.


Figure 1 shows the organization of the production line that works as follows. A type "A" machine takes a job from the input container, performs operation "A" and puts the job into the intermediate container.
A type "B" machine takes a job from the intermediate container, performs operation "B" and puts the job into the output container. All machines can work in parallel and independently of each other, and the size of each container is unlimited. The machines
have different performance characteristics, a given machine requires a given processing time for its 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:

  • N, the number of jobs (1<=N<=1000).
  • M1, the number of type "A" machines (1<=M1<=30)
  • M2, the number of type "B" machines (1<=M2<=30)
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。每个操作只有一些机器能够完成。

Ioi96d1.gif

上图显示了按照下述方式工作的流水线的组织形式。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;
}

抱歉!评论已关闭.