题目大意:有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的和决定的,越大就越下面
#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;
}
时间: 2024-10-11 06:32:59