zoukankan      html  css  js  c++  java
  • 聪明的质检员

    Problem Description

    小 T 是一名质量监督员,最近负责检验一批矿产的质量。这批矿产共有n 个矿石,从1到n 逐一编号,每个矿石都有自己的重量wi 以及价值vi。检验矿产的流程是:
      1、给定m 个区间[Li,Ri];
      2、选出一个参数W;
      3、对于一个区间[Li,Ri],计算矿石在这个区间上的检验值Yi :

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

    Input Format

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

    Output Format

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

    Algorithm Design

    二分答案+前缀和

    Problem Analysis

       求最接近标准的答案,很明显二分答案。当然二分Y明显很困难,应该分治W的值。这里又可以引入离散化思想,因为W一定是一个矿的质量,不然不会有变化。确定W之后就是怎么求Y的问题,首先要读懂题目,其实意思很简单,就是一个区间内可行矿的数量*可行矿的价值总和,因为区间老是重叠,如果循环处理,最大可能达到O(nm),所以想到前缀和处理,纪录1到i的可行矿数量和价值总和(一开始还想到线段树..),最后就是O((n+m)logn)的算法

    Source Code

     1 #include <bits/stdc++.h>
     2 #define MAXN 200010
     3 #define ll long long
     4 
     5 using namespace std;
     6 
     7 int n,m;
     8 ll s,ans,sumx[MAXN];
     9 int w[MAXN],v[MAXN],b[MAXN],e[MAXN],sortw[MAXN],sum[MAXN];
    10 
    11 void search(int l,int r)
    12 {
    13     if(l==r-1)
    14         return ;
    15     int mid=(l+r)>>1;
    16     ll y=0;
    17     for(int i=1;i<=n;i++)
    18     {
    19         sum[i]=sum[i-1];
    20         sumx[i]=sumx[i-1];
    21         if(w[i]>=sortw[mid])
    22             sum[i]+=1,sumx[i]+=v[i];
    23     }
    24     for(int i=1;i<=m;i++)
    25         y+=(sum[e[i]]-sum[b[i]-1])*(sumx[e[i]]-sumx[b[i]-1]);
    26     ans=min(ans,abs(y-s));
    27     if(y<s)
    28         search(l,mid);
    29     else 
    30         search(mid,r);
    31 }
    32 
    33 int main()
    34 {
    35     freopen("qc.in","r",stdin);
    36     freopen("qc.ans","w",stdout);
    37     cin>>n>>m>>s;
    38     for(int i=1;i<=n;i++)
    39         cin>>w[i]>>v[i],sortw[i]=w[i];
    40     for(int i=1;i<=m;i++)
    41         cin>>b[i]>>e[i];
    42     sort(sortw+1,sortw+n+1);
    43     ans=1000000000001;
    44     search(0,n+1);
    45     cout<<ans<<endl;
    46     return 0;
    47 }
    View Code
  • 相关阅读:
    若依启动非常慢
    【转】上火了一吃就好的食物
    实型输入控制
    【转】中国地理的几个概念
    如何在阅读邮件时时保留原有html格式正文的样式
    好的代码不是设计出来的,而是重构出来的
    .net用OLEDB方式操作SqlServer和Sybase
    悬浮框实现
    C#操作xml SelectNodes,SelectSingleNode总是返回NULL 与 xPath 介绍
    ODBC驱动重新注册
  • 原文地址:https://www.cnblogs.com/qswx/p/9411310.html
Copyright © 2011-2022 走看看