Job Processing_usaco4.2_贪心

52 篇文章 0 订阅
33 篇文章 0 订阅

Description


  一家工厂的流水线正在生产一种产品,这需要两种操作:操作A和操作B。每个操作只有一些机器能够完成。
这里写图片描述
  上图显示了按照下述方式工作的流水线的组织形式。A型机器从输入库接受工件,对其施加操作A,得到的中间产品存放在缓冲库。B型机器从缓冲库接受中间产品,对其施加操作B,得到的最终产品存放在输出库。所有的机器平行并且独立地工作,每个库的容量没有限制。每台机器的工作效率可能不同,一台机器完成一次操作需要一定的时间。
  给出每台机器完成一次操作的时间,计算完成A操作的时间总和的最小值,和完成B操作的时间总和的最小值。

Input


第一行 三个用空格分开的整数:N,工件数量 (1<=N<=1000);M1,A型机器的数量 (1<=M1<=30);M2,B型机器的数量 (1<=M2<=30)。
第二行…等 M1个整数(表示A型机器完成一次操作的时间,1..20),接着是M2个整数(B型机器完成一次操作的时间,1..20)

Output


只有一行。输出两个整数:完成所有A操作的时间总和的最小值,和完成所有B操作的时间总和的最小值(A操作必须在B操作之前完成)

Analysis


贪心。
对于第一问,我们每次寻找做完当前任务的最快且最早做完的机器,最后找的最大值就是答案

第二问可以看成是与第一问相同的子任务。为了达到最大值最小,我们要尽可能平均所有的总时间( Ai+Bi 尽可能小),那么当A完成的时间和B完成的时间有序时,任务i的最优解就是 Ai+Bni+1
也就是最久的搭配最快的

数据不大可以枚举找最小值,也可以用堆

Code


/*
ID:wjp13241
PROG:job
LANG:C++
*/
#include <stdio.h>
#include <string.h>
#include <queue>
#define INF 0x7f7f7f7f
#define N 1001
using namespace std;
struct job{
    int l,t;
    bool operator <(const job &x)const{return l+t>x.l+x.t;}
};
int a[N],b[N],f[N],t1[N],t2[N];
int max(int x,int y){return x>y?x:y;}
int main()
{
    freopen("job.in","r",stdin);
    freopen("job.out","w",stdout);
    int n,na,nb;
    scanf("%d%d%d",&n,&na,&nb);
    priority_queue<job>q;
    for (int i=1;i<=na;i++)
    {
        scanf("%d",&a[i]);
        q.push((job){0,a[i]});
    }
    int ans=0;
    for (int i=1;i<=n;i++)
    {
        job now=q.top();q.pop();
        ans=max(ans,now.l+now.t);
        now.l+=now.t;
        q.push(now);
        t1[i]=now.l;
    }
    while (q.size())
        q.pop();
    printf("%d ",ans);
    for (int i=1;i<=nb;i++)
    {
        scanf("%d",&b[i]);
        q.push((job){0,b[i]});
    }
    for (int i=1;i<=n;i++)
    {
        job now=q.top();q.pop();
        now.l+=now.t;
        q.push(now);
        t2[i]=now.l;
    }
    ans=0;
    for (int i=1;i<=n;i++)
        ans=max(ans,t1[i]+t2[n-i+1]);
    printf("%d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值