题目大意:多组询问,问每组,要买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.