POJ 3045 Cow Acrobats 贪心

Cow Acrobats [POJ-3045]

传送门:http://poj.org/problem?id=3045

Description
Farmer John’s N (1 <= N <= 50,000) cows (numbered 1…N) are planning to run away and join the circus. Their hoofed feet prevent them from tightrope walking and swinging from the trapeze (and their last attempt at firing a cow out of a cannon met with a dismal failure). Thus, they have decided to practice performing acrobatic stunts.

The cows aren’t terribly creative and have only come up with one acrobatic stunt: standing on top of each other to form a vertical stack of some height. The cows are trying to figure out the order in which they should arrange themselves ithin this stack.

Each of the N cows has an associated weight (1 <= W_i <= 10,000) and strength (1 <= S_i <= 1,000,000,000). The risk of a cow collapsing is equal to the combined weight of all cows on top of her (not including her own weight, of course) minus her strength (so that a stronger cow has a lower risk). Your task is to determine an ordering of the cows that minimizes the greatest risk of collapse for any of the cows.

Input

  • Line 1: A single line with the integer N.

  • Lines 2…N+1: Line i+1 describes cow i with two space-separated integers, W_i and S_i.

Output

  • Line 1: A single integer, giving the largest risk of all the cows in any optimal ordering that minimizes the risk.
Sample InputSample Output
3
10 3
2 5
3 3
2

题意:有n头牛牛一只踩在一只背上叠高高,每头牛有自己的重量和力量值,但他们这样做会有一个风险值,一头牛的风险值等于自身的重量加上踩在它身上的牛的总体重减去自身的力量值,

若编号为1的牛是最底下的牛,编号为n的牛是最上面的牛,则编号为i的牛的风险值s
s = ∑ k = i n a [ k ] . w − a [ i ] . s s=\sum_{k=i}^na[k].w - a[i].s s=k=ina[k].wa[i].s

现求风险值最大的牛能达到的最小风险值是多少(最小化最大值

思路
已知一头牛的风险值
r i s = ∑ k = i + 1 n a [ k ] . w − ( a [ i ] . w + a [ i ] . s ) ris=\sum_{k=i+1}^na[k].w - (a[i].w+ a[i].s) ris=k=i+1na[k].w(a[i].w+a[i].s)
且第i头牛的风险值不会受到在它上面的牛的顺序影响
假设现在有 牛 1 牛_1 1 牛 2 牛_2 2,体重和力量值分别对应 w 1 w_1 w1, s 2 s_2 s2 w 2 w_2 w2, s 2 s_2 s2,牛1和牛2挨着站,它们上面的牛的体重总和为 s u m sum sum


情况a:若牛1在牛2背上

牛1风险值为: r i s a 1 = s u m − s 1 risa_1=sum-s_1 risa1=sums1
牛2风险值为: r i s a 2 = s u m + w 1 − s 2 risa_2=sum+w1-s2 risa2=sum+w1s2


情况b:若牛2在牛1背上

牛1风险值为: r i s b 1 = s u m + w 2 − s 1 risb_1=sum+w2-s1 risb1=sum+w2s1
牛2风险值为: r i s b 2 = s u m − s 2 risb_2=sum-s2 risb2=sums2

现在要使得牛1在牛2背上的情况更优,即情况a中最大的风险值小于情况b中最大的风险值 r i s a 2 < r i s b 1 risa_2<risb_1 risa2<risb1

s u m + w 1 − s 2 < s u m + w 2 − s 1 sum+w_1-s_2<sum+w_2-s_1 sum+w1s2<sum+w2s1

w 1 + s 1 < w 2 + s 2 w_1+s_1<w_2+s_2 w1+s1<w2+s2
这样我们可以根据 w + s w+s w+s的大小进行排序,最小的站在牛堆的最顶端,从上到下计算风险值,不断更新最大值。此时得到的最大值一定是所有情况中最小的。

#include<iostream>
#include<algorithm>
using namespace std ;
#define ll long long
const ll N = 1e6+9 ;
void updata( ll &a , ll b ){if(b>a)a=b;}
struct node{
    ll w , s ;
}c[ N ];
bool cmp( node a , node b ){
    return (a.s+a.w)>(b.s+b.w) ;//从大到小排序
}
ll n , s , w ;
int main(){
    //while( cin >> n ){
        ios::sync_with_stdio(false);
        cin >> n ;
        ll sum = 0 , ans = -1e18 ;
        for( int i = 1 ; i <= n ; i ++ ){ cin >> c[ i ].w >> c[ i ].s ; sum += c[ i ].w ; }
        sort( c+1 , c+1+n , cmp ) ;
        for( int i = 1 ; i <= n ; i ++ ){
        //从最底下的牛开始算风险值
            ll tmp = sum-c[i].w-c[i].s ;
            updata( ans , tmp ) ;
            sum -= c[ i ].w ;
        }
        cout << ans << "\n" ;
   // }
return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值