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

    题意:n个物品每个有一个重量w和价值v

       然后给定m个区间

       定义区间价值   

       $y=(sum_j1)*(sum_jv[j]) w[j] ge W,j epsilon [l_i,r_i]$

       找到一个W   

       使这些区间价值和-S的绝对值最小

       输出最小值

    思路:二分+前缀和

       y无法直接相减,但是求y 的两部分可以直接相减

       对于二分

       如果当前价值和>S 说明限制可能有点小,导致满足的多,所以当前价值和大,因此我们要加大W限制,让其变小,才能让答案更小

       同理,如果<S,就减小W的限制

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define int long long
    #define olinr return
    #define _ 0
    #define love_nmr 0
    #define DB double
    struct node
    {
        int fir;
        int sec;
    }sm[205050];
    int n;
    int m;
    int s;
    int w[205050];
    int v[205050];
    int L[205050];
    int R[205050];
    int maxwight;
    int ans=0x7fffffffffffffff;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    inline int abss(int x)
    {
        if(x<0)
            return -x;
        return x;
    }
    inline void ok(int W,int &now)
    {
        for(int i=1;i<=n;i++)
        {
            sm[i].fir=sm[i-1].fir;
            sm[i].sec=sm[i-1].sec;
            if(w[i]>=W)
            {
                sm[i].fir++;
                sm[i].sec+=v[i];
            }
        }
        for(int i=1;i<=m;i++)
        {
            now+=(sm[R[i]].fir-sm[L[i]-1].fir)*(sm[R[i]].sec-sm[L[i]-1].sec);
        }
    }
    signed main()
    {
        n=read();
        m=read();
        s=read();
        for(int i=1;i<=n;i++)
        {
            w[i]=read();
            v[i]=read();
            maxwight=max(maxwight,w[i]);
        }
        for(int i=1;i<=m;i++)
        {
            L[i]=read();
            R[i]=read();
        }
        int l=0;
        int r=maxwight+1;
        int nowans=0;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            nowans=0;
            ok(mid,nowans);
            ans=min(ans,abss(nowans-s));
            if(nowans>s)
                l=mid+1;
            else if(nowans<s)
                r=mid-1;
            else
            {
                ans=0;
                break;
            }
            
        }
        put(ans);
        olinr ~~(0^_^0)+love_nmr;
    }
  • 相关阅读:
    跨域请求剖析
    MongoDB 创建索引及其他
    MongoDB的常用操作总结
    Vue学习【第四篇】:Vue 之webpack打包工具的使用
    转载:官方Caffe-windows 配置与示例运行
    转载:基于HALCON的模板匹配方法总结
    机器视觉硬件相关
    opencv画出轮廓外接矩形
    转载:approxPolyDP函数
    转载:return *this和return this
  • 原文地址:https://www.cnblogs.com/olinr/p/9532013.html
Copyright © 2011-2022 走看看