聰明的質監員(codevs 1138)題解

【問題描述】

小 T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有n 個礦石,從1到n 逐一編號,每個礦石都有自己的重量wi 以及價值vi。檢驗礦產的流程是:見圖

若這批礦產的檢驗結果與所給標準值S 相差太多,就需要再去檢驗另一批礦產。小T不想費時間去檢驗另一批礦產,所以他想通過調整參數W 的值,讓檢驗結果儘可能的靠近標準值S,即使得S-Y 的絕對值最小。請你幫忙求出這個最小值。

【樣例輸入】

    5 3 15
    1 5
    2 5
    3 5
    4 5
    5 5
    1 5
    2 4
    3 3

【樣例輸出】

    10

【解題思路】

    本題爲NOIP2011day2第二題,可能很多人不會的原因是因爲公式看不懂,先解釋一下,Yi的公式是指(符合條件的j的總數)*(vj的和)。現在我們來分析一下題目。題目中說,讓我們找一個合適的W的值使得Yi的和與給定的S之差的絕對值最小。由於題目中說j的要求是區間中Wi大於W的礦石,因此,我們可以確定W的範圍爲minwi-1~maxwi+1。在minwi-1以下的與minwi-1的值相同(全部可以取),同理,maxwi+1以上的與maxwi的值相同(全部不能取)。由於題目中說S-Y的絕對值最小,因此我們可以肯定Y可能>S也可能<S,那麼我們將W所可以取的區間二分,如果所得到的Y>S,我們就往右邊的區間找,否則往左邊的區間找,50分就到手了。

    剩下的50分需要用到一個強大的技巧,也是許多區間問題中非常重要的一個技巧,那就是前綴和。當我們枚舉所有礦石中Wi>W的礦石的時候,用一個數組存儲,將所有的都算出來,這樣,在求某個區間的時候,就只要將右節點的值減去左節點-1的值,即所求的區間了,整個過程是n+m,比m*(r-l)快多了。

【代碼實現】

 1 type rec=record
 2      w,v:int64;
 3 end;
 4 var i,j:longint;
 5     sum,min,w,v,n,m,s,minw,maxw,l,r,mid:int64;
 6     a,b:array[0..200010] of rec;
 7     sumv,sumw:array[0..200010] of int64;
 8 function get(x:int64):int64;
 9 var i,j:longint;
10 begin
11  fillchar(sumv,sizeof(sumv),0);
12  fillchar(sumw,sizeof(sumw),0);
13  get:=0;
14  for i:=1 to n do
15   if a[i].w>x then
16    begin
17     sumv[i]:=sumv[i-1]+a[i].v;
18     sumw[i]:=sumw[i-1]+1;
19    end
20   else
21    begin
22     sumv[i]:=sumv[i-1];
23     sumw[i]:=sumw[i-1];
24    end;
25  for j:=1 to m do
26   inc(get,(sumw[b[j].v]-sumw[b[j].w-1])*(sumv[b[j].v]-sumv[b[j].w-1]));
27 end;
28 begin
29  minw:=maxlongint;
30  readln(n,m,s);
31  for i:=1 to n do
32   with a[i] do
33    begin
34     readln(w,v);
35     if w>maxw then
36      maxw:=w;
37     if w<minw then
38      minw:=w;
39    end;
40  for i:=1 to m do
41   with b[i] do
42    readln(w,v);
43  l:=minw-1;
44  r:=maxw+1;
45  min:=9223372036854775800;
46  repeat
47   mid:=(l+r) div 2;
48   sum:=get(mid);
49   if abs(sum-s)<min then
50    min:=abs(sum-s);
51   if sum>s then
52    l:=mid+1
53   else
54    r:=mid-1;
55  until l>r;
56  writeln(min);
57 end.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章