CODE[VS] 1138 聪明的质检员 二分+前缀和

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36404449/article/details/78276906

题目地址

题目描述 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
输出只有一行,包含一个整数,表示所求的最小值。
水题分析 Waterproblem Analysis
也是夏令营二分的必讲题,因为是对于区间求和而且区间数目多不方便暴力枚举,就很显然是要求一个前缀和了,对于每一个二分值求一个前缀和即可。注意数据范围比较大,用long long类型就可以过了。这个题比较水,而且不是DP不用过多分析,就显得的整篇博文很短,其实没什么关系,只要贴一个代码就很长了。

附上代码:

#include<iostream>
#include<cmath>
#include<cstdio> 
#define ll long long
#define MAXN 200010
using namespace std;
ll n,m,s;
int w[MAXN],v[MAXN];
long long dv[MAXN],t[MAXN],ans=0;
long long anss=21474836400006;
struct re
{
    int l,r;
}q[MAXN]; 
inline ll get_num()
{
    ll num=0;
    char c;
    bool flag=1;
    while((c=getchar())=='\n'||c=='\r'||c==' ');
    if(c=='-')flag=0;
    else num=c-'0';
    while(isdigit(c=getchar()))
    num=num*10+c-'0';
    return num*(flag?1:-1);
}
bool cheak(ll mid)
{
    for(int i=1;i<=n;i++)
    {
        if(w[i]>=mid)
        {
            t[i]=t[i-1]+1;
            dv[i]=dv[i-1]+v[i];
        }
        else
        {
            t[i]=t[i-1];
            dv[i]=dv[i-1];
        }
    }
    ans=0;
    for(int i=1;i<=m;i++)
    {
        ans+=(dv[q[i].r]-dv[q[i].l-1])*(t[q[i].r]-t[q[i].l-1]);
    }
    ll x=abs(ans-s);
    anss=min(anss,x); 
    if(ans>=s)return 1;
    else return 0;
}
int main()
{
    n=get_num();m=get_num();s=get_num();
    for(int i=1;i<=n;i++)
    {
        w[i]=get_num();
        v[i]=get_num();
    }
    for(int i=1;i<=m;i++)
    {
        q[i].l=get_num();
        q[i].r=get_num();
    }
    ll l=1,r=2147483646000;//这里之前r过小也没有AC
    while(l<=r)
    {
        ll mid=(l+r)>>1;
        if(cheak(mid))l=mid+1;
        else r=mid-1; 
    }
    cout<<anss;
}

猜你喜欢

转载自blog.csdn.net/qq_36404449/article/details/78276906