• 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;
    }
    

      

  • 相关阅读:
    设计模式-17-迭代器
    设计模式-16-备忘录
    微服务架构设计
    数据库拆分案例
    生成多个git ssh密钥
    分布式数据中间件TDDL、Amoeba、Cobar、MyCAT架构比较
    maven工程 java 实现文件上传 SSM ajax异步请求上传
    MySQL的分区、分表、集群
    Redis实现分布式锁原理与实现分析
    关于消息队列的使用
  • 原文地址:https://www.cnblogs.com/carcar/p/10905108.html
Copyright © 2020-2023  润新知