USACO-Section 4.2 Job Processing (贪心)

来源:互联网 发布:http传输数据 编辑:程序博客网 时间:2024/05/16 11:31

描述

一家工厂的流水线正在生产一种产品,这需要两种操作:操作A和操作B。每个操作只有一些机器能够完成。

Ioi96d1.gif

上图显示了按照下述方式工作的流水线的组织形式。A型机器从输入库接受工件,对其施加操作A,得到的中间产品存放在缓冲库。B型机器从缓冲库接受中间产品,对其施加操作B,得到的最终产品存放在输出库。所有的机器平行并且独立地工作,每个库的容量没有限制。每台机器的工作效率可能不同,一台机器完成一次操作需要一定的时间。

给出每台机器完成一次操作的时间,计算完成A操作的时间总和的最小值,和完成B操作的时间总和的最小值。

注:1、机器在一次操作中干掉一个工件; 2、时间总和的意思是最晚时间点

格式

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 31 1 3 1 4

SAMPLE OUTPUT

3 5

完成A操作的时间总和最小值很容易想到

但是完成B操作的时间总和最小值还不是能理解,觉得A操作完成的时间对B操作的时间影响很大

贴一下别人的证明:

问题证明

by true(cai 教的)

现在来证明为什么在第一步最优的前提下能得出第二步最优: 假设在A已经最优的前提下,可以把一个零件拿出放到另一个A的机器上,使得B最后的结果比当前好,那么假设这两台A机器为A1,A2,对应的两台B机器为B1,B2.对应的时间有分别是a1,a2,b1,b2.且a2>=a1,b2>=b1,a2/2<=a1<=a2,b2/2<=b1<=b2. 那么原来A最优时的结果应该是max1{a1+b2,a2+b1},而现在如果把A的一个机器(假设是A2)的零件放到了A1上,那么现在的最优值就为 max2{a1+a2+b1,b2},现在只要证明max1恒<=max2就可以了,分四种情况证明: 一:

假设:     a2+b1>=a1+b2,     b2>=a1+a2+b1     且b2<a2+b1.    证明:     由a2+b1>=a1+b2  =>   a2+b1>=b2  (1)     由b2>=a1+a2+b1  =>   a2+b1<=b2  (2)     综合(1)(2)可知  a2+b1=b2 与假设矛盾.

二:

假设:     a2+b1>=a1+b2,     a1+a2+b1>=b2     且a1+a2+b1<a2+b1  <<=  显然不成立

三:

假设:     a1+b2>=a2+b1, (1)     b2>=a1+a2+b1     且b2<a1+b2  (4)证明:   由b2>=a1+a2+b1  =>  b2-a1>=a2+b1  (2)  (1)+(2)  =〉 b2>=a2+b1  (3)   (3)(4)矛盾。

四:

假设:      a1+b2>=a2+b1,   (1)      a1+a2+b1>=b2    (2)    且a1+a2+b1<a1+b2  (3)证明:     现在对不等式进行一种等价变换,在不影响(1)(2)不等式符号和a1+b2,a1+a2+b1的差的     前提下,来试图证明不等式(3)是不可能的    让a1=a2,则(1)==>>  a2+b2>=a2+b1                (2)==>>  2a2+b1>=b2                (3)==>>  2a2+b1<a2+b2       观察(2),(3),应为a2>=0,所以显然是不可能同时成立的,所以问题得证。

即:

在A为最优的前提下一定能够造出一个问题二也是最优的解。

/*ID: your_id_herePROG: jobLANG: C++*/#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;int n,am,bm,ans;int a[205],b[205],atime[1005],btime[1005];struct aNode {    int index,time;    bool operator < (const aNode& x) const{        return (time+a[index])>(x.time+a[x.index]);    }}u;struct bNode {    int index,time;    bool operator < (const bNode& x) const{        return (time+b[index])>(x.time+b[x.index]);    }}v;priority_queue<aNode> aq;priority_queue<bNode> bq;int main() {    freopen("job.in","r",stdin);    freopen("job.out","w",stdout);    scanf("%d%d%d",&n,&am,&bm);    u.time=0;    for(int i=0;i<am;++i) {        scanf("%d",a+i);        u.index=i;        aq.push(u);    }    for(int i=0;i<n;++i) {//每次取最终时间最小的出来加工        u=aq.top();        aq.pop();        u.time+=a[u.index];        atime[i]=u.time;        aq.push(u);    }    v.time=0;    for(int i=0;i<bm;++i) {        scanf("%d",b+i);        v.index=i;        bq.push(v);    }    for(int i=0;i<n;++i) {//每次取最终时间最小的出来加工        v=bq.top();        bq.pop();        v.time+=b[v.index];        btime[i]=v.time;        bq.push(v);    }    sort(atime,atime+n);    sort(btime,btime+n);    ans=0;    for(int i=0;i<n;++i)        ans=max(ans,atime[i]+btime[n-i-1]);    printf("%d %d\n",atime[n-1],ans);    return 0;}


0 0