二分 前缀和 聪明的质检员 洛谷P1314

逃离我推掉我的手 2021-11-29 13:10 343阅读 0赞

题目链接:https://www.luogu.org/problemnew/show/P1314

题意:给出n个产品的重量w和价值v,给定m个区间,每个区间通过一个包含参数W的式子来计算,使总的值逐渐逼近一个值S

1448994-20190720175025983-1479228305.png

分析:很明显W为0时,所有产品都满足,此时Y最大,当W比重量w的最大值还大时,所有产品都不满足,此时Y最小,可以明显看出单调性,我们可以采用二分的方法来做

二分的话如果每次判断的话都是一个一个区间的求,时间复杂度为O(N*M),我们得用前缀和将之优化为O(N)

对于每一个W,进行前缀和的时候,如果对应的重量w比W大,则sum数组加上当前数,否则则不加。

另外,题目是要让我们尽可能的靠近标准值,所以二分的时候要另外用一个数ans来记录

这里介绍一个绝对值函数:llabs()能够求ll数的绝对值。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int mod=1e9+7;
  5. const int maxn=2e5+7;
  6. const ll inf=1e18+7;
  7. const double pi=acos(-1);
  8. ll ans=inf,res=inf;
  9. ll n,m,s;
  10. ll sum[maxn],sum_n[maxn],w[maxn],v[maxn],l[maxn],r[maxn];
  11. bool isok(int x){
  12. ll y=0;
  13. memset(sum,0,sizeof(sum));
  14. memset(sum_n,0,sizeof(sum_n));
  15. for(int i=1;i<=n;i++){
  16. if(w[i]>=x) sum[i]=sum[i-1]+v[i],sum_n[i]=sum_n[i-1]+1;
  17. else sum[i]=sum[i-1],sum_n[i]=sum_n[i-1];
  18. }
  19. for(int i=0;i<m;i++){
  20. y+=(sum_n[r[i]]-sum_n[l[i]-1])*(sum[r[i]]-sum[l[i]-1]);
  21. }
  22. //cout<<y<<" "<<s<<endl;
  23. res=llabs(y-s);
  24. //cout<<res<<endl;
  25. if(s>y)return false;
  26. else return true;
  27. }
  28. int main(){
  29. cin>>n>>m>>s;
  30. ll mn=inf,mx=-1;
  31. for(int i=1;i<=n;i++){
  32. scanf("%lld%lld",&w[i],&v[i]);
  33. mn=min(mn,w[i]);
  34. mx=max(mx,w[i]);
  35. }
  36. for(int i=0;i<m;i++){
  37. scanf("%d%d",&l[i],&r[i]);
  38. }
  39. int left=mn-1,right=mx+2;//右边界如果只取到mx,则包含不了所有矿石都不满足的情况,mn同理
  40. while(left<=right){
  41. int mid=(left+right)/2;
  42. if(isok(mid)) left=mid+1;
  43. else right=mid-1;
  44. if(res<ans) ans=res;
  45. //cout<<ans<<endl;
  46. }
  47. cout<<ans<<endl;
  48. return 0;
  49. }

转载于:https://www.cnblogs.com/qingjiuling/p/11220254.html

发表评论

表情:
评论列表 (有 0 条评论,343人围观)

还没有评论,来说两句吧...

相关阅读

    相关 p1164

    > P1164 小A点菜 > > 题目描述 > > uim口袋里有剩M元(M<=10000)。 > > 餐馆虽低端,但是菜品种类不少,有N种(N<=100),第i

    相关 P3382

    题目:[点击打开链接][Link 1] 题意:如题,给出一个N次函数,保证在范围\[l,r\]内存在一点x,使得\[l,x\]上单调增,\[x,r\]上单调减。试求出x