hdu 1394 Minimum Inversion Number 线段树

题目:给一个数列,求在不停地把第一个数字放到末尾时最少的逆序对数。

分析:这题我一开始想的太复杂了,后来看题解才发现其实很水的。一开始先用线段树、树状数组或归并排序求逆序对,然后再递推每一次操作后的逆序对数就好了。

下面附程序:

var
  n,ans,i,s:longint;
  a:array[1..5000] of longint;
  t:array[1..15000,1..3] of longint;

procedure hehe(d,l,r:longint);
var
  m:longint;
begin
  t[d,1]:=l;
  t[d,2]:=r;
  t[d,3]:=0;
  if l=r then exit;
  m:=(l+r) div 2;
  hehe(d*2,l,m);
  hehe(d*2+1,m+1,r);
end;

function work(d,x:longint):longint;
var
  m:longint;
begin
  inc(t[d,3]);
  if t[d,1]=t[d,2] then exit(0);
  m:=(t[d,1]+t[d,2]) div 2;
  if x<=m
    then work:=work(d*2,x)+t[d*2+1,3]
    else work:=work(d*2+1,x);
end;

begin
  while not eof do
  begin
    readln(n);
    hehe(1,1,n);
    s:=0;
    for i:=1 to n do
    begin
      read(a[i]);
      inc(a[i]);
      s:=s+work(1,a[i]);
    end;
    readln;
    ans:=s;
    for i:=1 to n-1 do
    begin
      s:=s-a[i]+1+n-a[i];
      if s<ans then ans:=s;
    end;
    writeln(ans);
  end;
end.


你可能感兴趣的:(hdu 1394 Minimum Inversion Number 线段树)