I and OI
Past...

题意: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.
posted on 2011-08-13 14:28  exponent  阅读(866)  评论(0编辑  收藏  举报