POJ 3045 Cow Acrobats

来源:互联网 发布:淘宝找同款插件 编辑:程序博客网 时间:2024/05/20 03:45

需要注意事项:

题目要求的答案是可以为负数的,我因为加了主观判断,以为只能大于0,所以WA了一次

思考过程:

一开始想的就是先二分一下答案,最后发现不需要二分。

我们假设有一个放法,从下而上的牛的编号是:a1,a2,a3.....an

那这n头牛的难受程度依次是

q[1] = Sum - (W[a1] + S[a1])

q[2] = Sum - (W[a1]) - (W[a2] + S[a2])

q[3] = Sum - (W[a1] + W[a2]) - (W[a3] + S[a3])

q[4] = Sum - (W[a1] + W[a2]+W[a3]) - (W[a4] + S[a4])

.........

(注明:Sum是所有牛的重量之和,W[i]是i号牛的重量,S[i]是i号牛的力量)

所以我们求的就是最小的ans = max{q[1],q[2],.....,q[n-1],q[n]}

那有没有一种放法可以使max{q[1],q[2],.....,q[n-1],q[n]}最小呢?

如果根据 W[i]+S[i] 的大小,从大到小的顺序,从下往上放。这样的放法可不可以使max{q[1],q[2],.....,q[n-1],q[n]}最小呢?

我先证明了一下在这个放法的基础上交换任意两个牛的位置都不会使max{q[1],.....,q[n]}增大

但感觉证明不够充分,然后又将这个方法与二分+贪心的方法进行比对,发现结果只会比二分+贪心的方法更好。


我的代码:

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <algorithm>using namespace std;struct cow{int W,S,SUM;};const int MAX=1000000000;cow a[100000];int n;int cmp(cow x, cow y){return x.SUM>y.SUM;}int main(){int i,j,sum,ans;scanf("%d",&n);sum = 0;for (i=0;i<n;i++){scanf("%d%d",&a[i].W,&a[i].S);a[i].SUM = a[i].W + a[i].S;sum += a[i].W;}sort(a, a+n, cmp);ans = MAX*-1;for (i=0;i<n;i++){if (sum-a[i].SUM>ans)ans = sum - a[i].SUM;sum -= a[i].W;}printf("%d",ans);return 0;}



Sum - (W[a1]) - (W[a2] + S[a2])
0 0