描述
一家工厂的流水线正在生产一种产品,这需要两种操作:操作A和操作B。每个操作只有一些机器能够完成。
上图显示了按照下述方式工作的流水线的组织形式。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 3 1 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_here
PROG: job
LANG: 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;
}