USACO 二道工序

Description

每天早晨,约翰的 N 头奶牛都要排队接受挤奶。为了提高效率,约翰把挤奶过程分成了两道工 序。约翰负责第一道工序,第二道工序则让他的好友罗伯帮忙。奶牛们进入牛棚后,首先在约翰处排 队,依次接受第一道工序,完成后再去罗伯处排队,接受第二道工序。挤奶过程中没有奶牛插队或者 开小差,约翰和罗伯是工作狂,中途不会休息,直到挤完所有奶牛的牛奶。

约翰发现,如果奶牛的排队顺序不加规划,可能会浪费很多时间。比如一些奶牛的第一道工序很 长,那么罗伯就会有很长一段时间无事可做。请你帮助约翰计算一下,应该让奶牛按照什么样的规律 排队,才能最节约时间。

Input Format

• 第一行:单个整数 N ,1 ≤ N ≤ 25000

• 第二行到第 N + 1 行:第 i + 1 行有两个整数 Ai 和 Bi,分别表示第 i 头奶牛接受第一道工序 和第二道工序所需要的时间,1 ≤ Ai,Bi ≤ 2000

Output Format

单个整数:表示最少需要多少时间才能挤完所有奶牛的牛奶

Sample Input

3
2 2
7 4
3 5

Sample Output

16
解释
排队顺序应该是第三头,第一头,第二头
solution

对于两头牛a,b;
满足下面条件时a应该在b之前:
max(A1+B1+B2, A1+A2+B2)<=max(A2+B2+B1, A2+A1+B1)
化简:
max(A2, B1)+A1+B2<=max(A1, B2)+A2+B1
max(A2, B1)-A2-B1<=max(A1, B2)-A1-B2
-min(A2, B1)<=-min(A1, B2)
min(A1, B2)<=min(A2, B1)

一道比较好的局部调整法贪心题

#include<cstdio>
#include<algorithm>
inline int min(int a,int b){a-=b;return b+(a&(a>>31));}
inline int max(int a,int b){a-=b;return b+(a&(~a>>31));}
int N,T1,T2;
struct info{int A,B;}cow[25012];
bool cmp(info x,info y){return min(x.A,y.B)<min(x.B,y.A);}
int main()
{
    scanf("%d", &N);
    for(int g=1;g<=N;++g) scanf("%d%d", &cow[g].A,&cow[g].B);
    std::sort(cow+1,cow+N+1,cmp);
    for(int g=1;g<=N;++g)
    {
        if(T1>T2) T2=T1;
        T1+=cow[g].A; T2=max(T1,T2)+cow[g].B;
    }
    printf("%d", T2);
    return 0;
}

 

 

转载于:https://www.cnblogs.com/HollowM/p/7795151.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值