题目大意:多组询问,问每组,要买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.
来源:https://www.cnblogs.com/wmzisfoolish/archive/2012/05/03/2480695.html
