题意:N头牛叠罗汉,每头牛有个体重Wi,力气Si.一头牛要承担的风险为所有在它上面的牛的体重之和-它的力气.
求一个方案使得风险最大的牛的风险值最小.
分析:对于相邻的两头牛,它们交换位置不影响其他的任何牛,只改变这两头牛的风险值.
记sum为这两头牛上面的牛的体重总和.i在j上面
Riski=sum-si
Riskj=sum+wi-sj
交换位置
Riski'=sum+wj-si
Riskj'=sum-sj
方案1优于方案2,则max{Riski,Riskj}<max{Riski',Riskj'}
而Riskj>Riskj'
所以Riski'>max{Riski,Riskj},且Riski'>Riskj'.
解之得
wj-si>sj
wj-si>wi-sj
wj-si>si
我们只需要中间的一条.记ti=si+wi
则方案1优于方案2等价于ti<tj,即ti小的在上会更优.
算法就简单了,排序,统计一遍就好了.
code:
type cow=record w,s,t:longint; end; const oo=maxlongint; maxn=50001; var c:array[0..maxn] of cow; n,i,sum,ans,risk:longint; procedure sort(l,r:longint); var i,j,mid:longint; begin i:=l; j:=r; mid:=c[(l+r)>>1].t; while i<=j do begin while c[i].t<mid do inc(i); while c[j].t>mid do dec(j); if i<=j then begin c[0]:=c[i]; c[i]:=c[j]; c[j]:=c[0]; inc(i); dec(j); end; end; if i<r then sort(i,r); if j>l then sort(l,j); end; begin readln(n); for i:=1 to n do begin readln(c[i].w,c[i].s); c[i].t:=c[i].w+c[i].s; end; sort(1,n); sum:=0; ans:=-oo; for i:=1 to n do begin risk:=sum-c[i].s; if risk>ans then ans:=risk; sum:=sum+c[i].w; end; writeln(ans); end.