Description
农夫的N只牛(1<=n<=50,000)决定练习特技表演。 特技表演如下:站在对方的头顶上,形成一个垂直的高度。 每头牛都有重量(1 <= W_i <= 10,000)和力量(1 <= S_i <= 1,000,000,000)。奶牛崩溃的风险等同于她身上所有的奶牛的重量(当然不包括她自己)减去她的力量。你的任务是确定奶牛的顺序,从而使得所有牛的风险中最大的一个尽量小。
Input
第1行:一个整数N 第2 . .N+ 1行: 两个空格分隔的整数重量wi和力量si来描述奶牛i。
Output
一个整数,在所有牛的风险中最大的一个
Sample Input
3
10 3
2 5
3 3
Sample Output
2
Analysis
这看上去很像贪心题,但是怎么贪呢?
我们贪心时,如果对象多,而单独两个对象之间的差异对其他不影响,其他的也不对这两个对象有影响,就可以减少到两个方便分析。
对于i,j,设Di表示第i头奶牛的难受值,Wi表示第i头奶牛的体重,Si表示第i头奶牛的力量,令i,j相邻。
当i在j的上方时有当i在j的上方时有
- Di=−Si①
- Dj=Wi−Sj ②
当j在i的上方时有当j在i的上方时有
- Di=Wj−Si ③
- Dj=−Sj④
显然有②>④,③>①
那么最大值肯定在②,③中间
不妨设②>③,(那意味着这时候j放在上面)
则Wi−Sj>Wj−Si => Wi+Si>Wj+Sj
我们便可以得出,以W+S排序,小的放在上面。
Code
1 #include<set> 2 #include<map> 3 #include<queue> 4 #include<stack> 5 #include<cmath> 6 #include<cstdio> 7 #include<cstring> 8 #include<iostream> 9 #include<algorithm> 10 #define RG register int 11 #define rep(i,a,b) for(RG i=a;i<=b;++i) 12 #define per(i,a,b) for(RG i=a;i>=b;--i) 13 #define ll long long 14 #define inf (1<<29) 15 #define maxn 50005 16 using namespace std; 17 int n,ans=-inf; 18 int sum[maxn]; 19 struct D{ 20 int w,s; 21 inline int operator < (const D &a)const{ 22 return w+s<a.w+a.s; 23 } 24 }num[maxn]; 25 inline int read() 26 { 27 int x=0,f=1;char c=getchar(); 28 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 29 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 30 return x*f; 31 } 32 33 int main() 34 { 35 n=read(); 36 rep(i,1,n) num[i].w=read(),num[i].s=read(); 37 sort(num+1,num+1+n); 38 rep(i,2,n) sum[i]=sum[i-1]+num[i-1].w; 39 rep(i,1,n) ans=max(ans,sum[i]-num[i].s); 40 cout<<ans; 41 return 0; 42 }