POJ 1018

题目大意:多组询问,问每组,要买n种零件,每种零件都有各自的m种选择,每种零件有两种属性:带宽b和价格p,求一种方案,有max(min(all_b)/sum(p))

解:discuss各种奇葩,无聊回去研究一下。我的做法是按b值排序,看b最大可以选多少(用多少b以上的能把n种零件买齐),如果fin点价格相同,则需要特殊处理,交换那些key点(使零件都有的点),再贪心,min[i] = 从i买到n的最小价格,然后枚举价格,从1 to fin即可,其实挺乱的,还是见程序吧。

View Code
  1 //Communication system
  2 const
  3         maxlen=10001;
  4         inf='1.txt';
  5 type
  6         data=record
  7           b, p, col: longint;
  8         end;
  9 var
 10         a: array[0..maxlen]of data;
 11         min: array[0..maxlen]of longint;
 12         tmp: array[0..100]of longint;
 13         fin, tot, test, wugu, m, n: longint;
 14         ans: extended;
 15 procedure qsort(b, e: longint);
 16 var
 17         i, j, x: longint;
 18         k: data;
 19 begin
 20   i := b; j := e; x := a[(i+j)>>1].b;
 21   repeat
 22     while a[i].b<x do inc(i);
 23     while a[j].b>x do dec(j);
 24     if i<=j then begin
 25       k := a[i]; a[i] := a[j]; a[j] := k;
 26       inc(i); dec(j);
 27     end;
 28   until i>j;
 29   if j>b then qsort(b, j);
 30   if i<e then qsort(i, e);
 31 end;
 32 
 33 procedure give(b, e: longint);
 34 var
 35         s, i, j: longint;
 36         rec: array[0..100]of longint;
 37 begin
 38   filldword(rec, sizeof(rec)>>2, maxlongint);
 39   for i := e to tot do
 40     with a[i] do
 41       if rec[col]>p then rec[col] := p;
 42   s := 0;
 43   for i := 0 to 100 do if rec[i]<>maxlongint then s := s + rec[i];
 44   for i := e downto b do
 45     with a[i] do begin
 46       if rec[col]>p then begin
 47         s := s - rec[col] + p;
 48         rec[col] := p;
 49       end;
 50       min[i] := s;
 51     end;
 52 end;
 53 
 54 function deal(x: longint): longint;
 55 var
 56         i, j: longint;
 57         k: data;
 58 begin
 59   i := x;
 60   while a[i].p=a[i+1].p do inc(i);
 61   j := i;
 62   while j>=x do begin
 63     dec(tmp[a[j].col]);
 64     if tmp[a[j].col]=0 then if j<i then begin
 65       k := a[i]; a[i] := a[j]; a[j] := k;
 66       dec(i);
 67     end;
 68     dec(j);
 69   end;
 70   deal := i;
 71 end;
 72 
 73 procedure init;
 74 var
 75         s, i, j: longint;
 76         k: data;
 77 begin
 78   fillchar(min, sizeof(min), 0);
 79   fillchar(tmp, sizeof(tmp), 0);
 80   tot := 0; ans := 0;
 81   readln(n);
 82   for i := 1 to n do begin
 83     read(m);
 84     for j := 1 to m do begin
 85       inc(tot);
 86       with a[tot] do begin
 87         read(b, p);
 88         col := i;
 89       end;
 90     end;
 91     readln;
 92   end;
 93   qsort(1, tot);
 94   s := n;
 95   for i := tot downto 1 do begin          {!!!}
 96     if tmp[a[i].col]=0 then begin
 97       dec(s);
 98     end;
 99     inc(tmp[a[i].col]);
100     j := i;
101     if s=0 then break;
102   end;
103   fin := deal(j);
104   give(1, fin);
105 end;
106 
107 procedure main;
108 var
109         i: longint;
110 begin
111   for i := 1 to fin do begin
112     if a[i].b/min[i]>ans then ans := a[i].b/min[i];
113   end;
114 end;
115 
116 procedure print;
117 begin
118   writeln(ans:0:3);
119 end;
120 begin
121   assign(input,inf); reset(input);
122   readln(wugu);
123   for test := 1 to wugu do begin
124     init;
125     main;
126     print;
127   end;
128 end.
posted @ 2012-05-03 15:39  F.D.His.D  阅读(206)  评论(0编辑  收藏  举报