CodeVS 1138-聪明的质检员

原题

题目描述 Description

小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从1到n逐一编号,每个矿石都有自己的重量wi以及价值vi.检验矿产的流程是:见图

若这批矿产的检验结果与所给标准值S相差太多,就需要再去检验另一批矿产.小T不想费时间去检验另一批矿产,所以他想通过调整参数W的值,让检验结果尽可能的靠近标准值S,即使得S-Y的绝对值最小.请你帮忙求出这个最小值.

输入描述 Input Description

第一行包含三个整数n,m,S,分别表示矿石的个数、区间的个数和标准值.
接下来的 n 行,每行2个整数,中间用空格隔开,第i+1行表示i号矿石的重量wi和价值vi.
接下来的 m 行,表示区间,每行2个整数,中间用空格隔开,第i+n+1 行表示区间[Li,Ri]的两个端点Li 和Ri.注意:不同区间可能重合或相互重叠.

输出描述 Output Description

输出只有一行,包含一个整数,表示所求的最小值.

样例输入 Sample Input

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

样例输出 Sample Output

10

提示 Hint

当 W 选4 的时候,三个区间上检验值分别为20、5、0,这批矿产的检验结果为25,此时与标准值S 相差最小为10.

数据范围 Data Size

对于 10%的数据,有1≤n,m≤10;
对于 30%的数据,有1≤n,m≤500;
对于 50%的数据,有1≤n,m≤5,000;
对于 70%的数据,有1≤n,m≤10,000;
对于 100%的数据,有1≤n,m≤200,000,0 < wi, vi≤106,0 < S≤1012,1≤Li≤Ri≤n.

题意

给出n个物品的重量w[i]和价值v[i],以及一个标准值S,并给出m个[l[i],r[i]]的区间.要求你找出一个数K,每次求出l[i]~r[i]的区间中,w[j]≥K{l[i]≤j≤r[i]}的物品数以及每个物品相对应的价值的和,并将两者相乘,乘积为X[i],再将m个X[i]相加得到P,使得abs(P-S)最小,并输出abs(P-S).

题解

首先二分K值,每次求出当参数=K时的检验结果与S的差,K的最大值为max(w[i]).

当样例的K分别等于{1,2,3,4,5,6}时,检验结果与S的差的绝对值分别为{160,115,55,10,10,15},设此序列为a[i].但是要怎么通过二分求出这个有序的单峰序列中最小的数呢?

我们可以先不考虑绝对值的情况,即原序列变为{160,115,55,10,-10,-15},这样便成了一个有序的下降序列,然后二分出大于等于0的最小值的位置.通过查找,我们发现这个序列二分后的答案为4,即序列中的10.

设p为现在二分后的答案4,则最终的答案ans=min(a[p],a[p+1]).因为我们二分出来的p值已经是正数这一边的绝对值最小值的位置,那我们只要让它与负数的绝对值最小值比较,最后输出较小的那个就好了.

然后记得每次二分都要O(n)维护两个前缀和,一个表示[1,i]的区间内有多少个w值是≥K的,另一个表示[1,i]的区间内的v值总和,因为w[i]是无序的.

代码如下:

 1 uses math;
 2 var w,ww,v,vv,l,r:array[0..200000] of longint;
 3 var ll,rr,mid,maxw,n,m,i,s,pp,ans:longint;
 4 function check(x:longint):longint;
 5 var i,sum:longint;
 6 begin
 7   sum:=0;
 8   for i:=1 to n do
 9   begin
10     ww[i]:=0;vv[i]:=0;//初始化前缀和数组
11     if w[i]>=x then
12     begin
13       ww[i]:=ww[i-1]+1;//前缀和
14       vv[i]:=vv[i-1]+v[i];//前缀和
15     end else begin ww[i]:=ww[i-1];vv[i]:=vv[i-1]; end;
16   end;
17   for i:=1 to m do sum:=(vv[r[i]]-vv[l[i]-1])*(ww[r[i]]-ww[l[i]-1])+sum;//检验值公式
18   exit(sum-s);//直接跳出差,而不是绝对值
19 end;
20 begin
21   readln(n,m,s);
22   for i:=1 to n do begin readln(w[i],v[i]);maxw:=max(maxw,w[i]); end;//求w[i]最大值定二分范围
23   for i:=1 to m do readln(l[i],r[i]);
24   rr:=maxw+1;ll:=1;
25   while ll+1<rr do
26   begin
27     mid:=(ll+rr)>>1;
28     if check(mid)>0 then ll:=mid else rr:=mid;
29   end;
30   ans:=min(abs(check(ll)),abs(check(ll+1)));//比较绝对值
31   writeln(ans);
32 end.

AC完这题之后我看了一下评测大厅,发现我的代码竟然是P党里的第二短23333333333333....

欢饮转载,请注明出处.

时间: 2024-10-23 12:52:57

CodeVS 1138-聪明的质检员的相关文章

[Codevs] 1138 聪明的质监员

1138 聪明的质监员 2011年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n 个矿石,从1到n 逐一编号,每个矿石都有自己的重量wi 以及价值vi.检验矿产的流程是:见图 若这批矿产的检验结果与所给标准值S 相差太多,就需要再去检验另一批矿产.小T不想费时间去检验另一批矿产,所以他想通过调整参数W 的值,让检验结果尽可能的靠近标准值

[NOIP 2011] 聪明的质检员

聪明的质检员 描述 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从1到n逐一编号,每个矿石都有自己的重量wi以及价值vi.检验矿产的流程是:1.给定m个区间[Li,Ri]:2.选出一个参数W:3.对于一个区间[Li,Ri],计算矿石在这个区间上的 检验值$Y_i$:\[Y_i=(\sum_j {1}) \times(\sum_j v_j) ,j \in [L_i,R_i] \land \: w_i \geqslant W\] 其中 $j$ 为矿石编号 这批矿产的 

【NOIP2011】聪明的质检员

Description 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从 1 到n逐一编号,每个矿石都有自己的重量wi以及价值vi.检验矿产的流程是: 1. 给定 m个区间[Li,Ri]: 2. 选出一个参数W: 3. 对于一个区间[Li,Ri],计算矿石在这个区间上的检验值Yi: 这批矿产的检验结果Y为各个区间的检验值之和.即: 若这批矿产的检验结果与所给标准值 S 相差太多,就需要再去检验另一批矿产.小 T 不想费时间去检验另一批矿产,所以他想通过调整参数 W

NOIP2011 聪明的质检员

描述 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从1到n逐一编号,每个矿石都有自己的重量wi以及价值vi.检验矿产的流程是:1.给定m个区间[Li,Ri]:2.选出一个参数W:3.对于一个区间[Li,Ri],计算矿石在这个区间上的检验值Yi:Yi=(∑j1)∗(∑jvj) ,  j∈[Li,Ri]且wj≥WYi=(∑j1)∗(∑jvj) ,  j∈[Li,Ri]且wj≥Wj是矿石编号 这批矿产的检验结果Y 为各个区间的检验值之和.即:Y=∑i=1mYiY=∑i=

NOIP2015聪明的质检员[二分 | 预处理]

背景 NOIP2011 day2 第二题 描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿产的流程是: 1 .给定m 个区间[Li ,Ri]: 2 .选出一个参数 W: 3 .对于一个区间[Li ,Ri],计算矿石在这个区间上的检验值Yi:Yi=Σ1*Σvj,Σ的循环变量为j,这里j要满足j∈[Li,Ri]且wj≥W,这里j是矿石编号. 这批矿产的检验结果Y为各个区间的检验值之和.ΣYi

Vijos P1740聪明的质检员

题目 描述 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从1到n逐一编号,每个矿石都有自己的重量wi以及价值vi.检验矿产的流程是:1.给定m个区间[Li,Ri]:2.选出一个参数W:3.对于一个区间[Li,Ri],计算矿石在这个区间上的检验值Yi:Yi = ∑1*∑vj,j∈[Li, Ri]且wj ≥ W,j是矿石编号这批矿产的检验结果Y 为各个区间的检验值之和.即:Y = ∑Yi,i ∈[1, m]若这批矿产的检验结果与所给标准值S相差太多,就需要再去检验另一

[题解]聪明的质检员

// 此博文为迁移而来,写于2015年7月14日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6ft.html 1.题目 2.TAG NOIP提高组:二分答案:前缀和. 3.分析 首先题面一定要看懂,看清(上次我就是没有看懂).说白了,就是使W取一个最合适的值,使每一个所给区间内满足条件的矿石的数量乘上价值之和,最后计算总和使与S最近. 我们根据分值分布来分析算法: 1.30分算法:O(n^3),首先O(n)进行W

CODEVS1138聪明的质检员2011T5

题目描述 Description 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n 个矿石,从1到n 逐一编号,每个矿石都有自己的重量wi 以及价值vi.检验矿产的流程是:见图 若这批矿产的检验结果与所给标准值S 相差太多,就需要再去检验另一批矿产.小T不想费时间去检验另一批矿产,所以他想通过调整参数W 的值,让检验结果尽可能的靠近标准值S,即使得S-Y 的绝对值最小.请你帮忙求出这个最小值. 思路: 题目描述...像个新定义的题...我真是...比较简单,可以看出w越大,y

洛谷 [P1314] 聪明的质检员(NOIP2011 D2T2)

一道二分答案加前缀和 题目中已经暗示的很明显了 "尽可能靠近" " 最小值" 本题的主要坑点在于 long long 的使用 abs函数不支持long long !!! #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; cons