• codeforces#1165 F2. Microtransactions (hard version) (二分+贪心)


    题目链接:

    https://codeforces.com/contest/1165/problem/F2

    题意:

    需要买$n$种物品,每种物品$k_i$个,每个物品需要两个硬币

    每天获得一个硬币

    有$m$个优惠

    在$d_i$天,$t_i$物品卖一个硬币

    求购买所需物品最少需要的天数

    数据范围:

    $1 le n, m le 2 cdot 10^5$

    分析: 

    我们可以注意到,如果某天是某个物品的最后优惠时间,那么我们一定要在这天尽可能多地购买这个物品

    对答案进行二分

    再二分得到每个物品在这个答案下的最后优惠时间

    贪心购买每种物品

    复杂度$O(lgn*lgn*n)$

    ac代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define pa pair<int,int>
    using namespace std;
    const int maxn=2e5+10;
    const ll mod=998244353;
    vector<int>ve[maxn];
    int sale[maxn*10],sum,num[maxn],n,m;
    bool check(int day)//检查天数为day时,能不能买完所以需要的东西
    {
        for(int i=1;i<=day;i++)sale[i]=0;//购买最后期限为i的物品数量
        for(int i=1;i<=n;i++)
        {
            if(ve[i].size()==0)continue;
            int st=0,en=(int)ve[i].size()-1;//二分每种物品的最后期限
            while(st!=en)
            {
                int md=(st+en)/2;
                if(ve[i][md+1]<=day)st=md+1;
                else en=md;
            }
            sale[ve[i][st]]+=num[i];
        }
        int money=0,buy=0;
        for(int i=1;i<=day;i++)//只要是最后期限,那么这个物品我们就买最多
        {
            money++;
            buy+=min(money,sale[i]);
            money-=min(money,sale[i]);
        }
        if(money>=2*(sum-buy))return 1;
        else return 0;
    }
    int main()
    {
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
            sum+=num[i];
        }
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d %d",&a,&b);
            ve[b].push_back(a);
        }
        for(int i=1;i<=n;i++)
            sort(ve[i].begin(),ve[i].end());
        
        int st=sum,en=2*sum;//对答案二分
        while(st!=en)
        {
            int md=(st+en)/2;
            if(check(md))en=md;
            else st=md+1;
        }
        printf("%d
    ",st);
        return 0;
    }
    

      

  • 相关阅读:
    [VC++入门]C++中常用的运算符及微软自定义类型
    搜索引擎蜘蛛爬虫原理
    Enterprise Library 5.0
    Installshield 12 中文系列教程之 定义安装必要条件
    installshield脚本
    c# 事物处理
    InStallShield网络资源参考
    Could not execute query against OLE DB provider 'OraOLEDB.Oracle'
    frameset小结
    最痛心的距离
  • 原文地址:https://www.cnblogs.com/carcar/p/10905108.html
Copyright © 2020-2023  润新知