Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

一个很巧妙的方法(附PASCAL程序)

Posted by noipchampion at 2011-10-31 22:37:16 on Problem 1018
首先,我们可以有一个很朴素的想法,就是依次枚举读入的n*m个东西的带宽为B,这样就只要使P尽量小就行了。而要使P尽量小,就要在每一类设备中选带宽大于等于B,而P又最小的那个。然而这个算法的复杂度是O(N²*M²),显然会超时。于是我们就要进行优化。

我们可以将每一类设备分别按带宽由小到大和价格由小到大排序的到两个数组F和S。然后按F数组来枚举n*m个东西(也就是带宽有小到大),按S数组来寻找带宽大于等于B,而P又最小的那个。由于S数组中价格递增,所以只需顺序找到第一个带宽大于等于B的就行了。但这个算法仍可能超时。我们发现由于F数组是按带宽递增的,所以我们在S数组中寻找时可以从上次找到的位置继续寻找,于是只要用一个Q数组来记录每次寻找到的位置即可。这样程序的复杂度就降为O(n²m),就可以AC了。
Code:
type
  node=record
         b,p:array[1..100] of longint;
         m:longint;
  end;

var s,f:array[1..100] of node;
    t,n:longint;

procedure init;
  var i,j:longint;

  begin
    fillchar(s,sizeof(s),0);
    fillchar(f,sizeof(f),0);
    readln(n);
    for i:=1 to n do
      begin
        read(s[i].m);
        for j:=1 to s[i].m do
          read(s[i].b[j],s[i].p[j]);
        readln;
      end;
  end;

procedure qsort1(num,l,r:longint);
  var i,j,x,temp:longint;

  begin
    i:=l;
    j:=r;
    x:=f[num].b[(l+r) shr 1];
    while i<j do
      begin
        while f[num].b[i]<x do inc(i);
        while x<f[num].b[j] do dec(j);
        if i<=j then
          begin
            temp:=f[num].b[i];
            f[num].b[i]:=f[num].b[j];
            f[num].b[j]:=temp;
            temp:=f[num].p[i];
            f[num].p[i]:=f[num].p[j];
            f[num].p[j]:=temp;
            inc(i);
            dec(j);
          end;
      end;
    if l<j then qsort1(num,l,j);
    if i<r then qsort1(num,i,r);
  end;

procedure qsort2(num,l,r:longint);
  var i,j,x,temp:longint;

  begin
    i:=l;
    j:=r;
    x:=s[num].p[(l+r) shr 1];
    while i<j do
      begin
        while s[num].p[i]<x do inc(i);
        while x<s[num].p[j] do dec(j);
        if i<=j then
          begin
            temp:=s[num].b[i];
            s[num].b[i]:=s[num].b[j];
            s[num].b[j]:=temp;
            temp:=s[num].p[i];
            s[num].p[i]:=s[num].p[j];
            s[num].p[j]:=temp;
            inc(i);
            dec(j);
          end;
      end;
    if l<j then qsort2(num,l,j);
    if i<r then qsort2(num,i,r);
  end;

procedure work;
  var q:array[1..100] of longint;
      i,j,k,sum:longint;
      ans:double;
      flag:boolean;

  begin
    for i:=1 to n do
      begin
        f[i]:=s[i];
        qsort1(i,1,f[i].m);
        qsort2(i,1,s[i].m);
      end;
    ans:=-1000000000;
    for i:=1 to n do
      begin
        for j:=1 to n do
          q[j]:=1;
        for j:=1 to f[i].m do
          begin
            sum:=f[i].p[j];
            flag:=true;
            for k:=1 to n do
              if i<>k then
                begin
                  while (s[k].b[q[k]]<f[i].b[j]) and (q[k]<=s[k].m) do
                    inc(q[k]);
                  if q[k]>s[k].m then begin flag:=false; break; end;
                  sum:=sum+s[k].p[q[k]];
                end;
            if not flag then break;
            if flag then
              if f[i].b[j]/sum>ans then ans:=f[i].b[j]/sum;
          end;
      end;
    writeln(ans:0:3);
  end;

begin
  read(t);
  while t>0 do
    begin
      t:=t-1;
      init;
      work;
    end;
end.

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator