您的位置:首页 > 其它

POJ - 3045 Cow Acrobats 贪心

2015-05-12 10:06 399 查看
题目大意:有N头牛要叠罗汉,每头牛都有相应的重量和力量。

叠罗汉是有危险的,每头牛的危险系数为该牛上面的牛的重量的和减去该牛的力量

问如何安排这个叠罗汉顺序,使得危险系数最大的那头牛的危险系数最小

解题思路:最大值的最小值,用二分?二分当然也可以,但是有更简便的方法

假设第i头牛的重量为wi,力量为si,第j头牛的重量为wj,力量为sj,第i头牛上面的牛的重量和sum

先考虑第一种情况,第i头牛叠到第j头牛的上面

那么 a1 = sum -si, b1 = sum + wi -sj

考虑第二种情况,第j头牛叠到第i头牛的上面

那么 a2 = sum - sj, b2 = sum + wj -si

先来考虑一下b1大于b2的情况

如果b1 > b2,那么wi + si > sj + wj

反之,如果b2 > b1那么 wj + sj > si + wi了

1.先假设 a1 > b1,那么可得sj > si + wi,b2 > a1 > b1 > a2,所以选择第一种叠法

同理可得 a2 > b2 时,si > sj + wj,选择第二种叠法

2.假设 a2 < a1, 因为b2 > a1, b1 > a2,所以这种情况下只需要判断是b1大还是b2大就可以了

最后可得到结论,当si + wi > sj + wj 时,就选择第二种叠法,反之,选择第一种叠法

也就是说,叠是根据si + wi的和决定的,越大就越下面

[code]#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 50010
struct Cows{
    int W, S;
}C[maxn];
int N;

bool cmp(const Cows a, const Cows b) {
    if(a.S + a.W == b.S + b.W)
        return a.W < b.W;
    return a.S + a.W < b.S + b.W;
}
void init() {
    for(int i = 0; i < N; i++) 
        scanf("%d%d", &C[i].W, &C[i].S);
    sort(C, C+N, cmp);
}

long long solve() {
    long long Sum = 0, Max = -0x3f3f3f3f;
    for(int i = 0; i < N; i++) {
        Max = max(Sum - C[i].S, Max);
        Sum += C[i].W;
    }
    return Max;
}

int main() {
    while(scanf("%d", &N) != EOF) {
        init();
        printf("%lld\n",solve());
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: