Codeforces 1165 F2 Microtransactions (hard version) —— 二分

This way

题意:

现在有m种物品,每种需要买ki个,每种物品一个都要花费2元,但是有些物品会在特定的天数花费减半。你从第一天开始,每天早上你会获得一元钱,每天晚上你会去买东西,你可以买任意多的东西(只要你有钱)。从第一天开始算,你至少需要几天才能买到所有需要的物品。

题解:

一开始题意看错了,我以为是从任意一天开始,那么对于这样的题目,二分依旧是二分,然后在判断的时候是两点维护一个区间向右移,然后找区间内最多可以买多少价格为1的物品。
那么从第一天开始的话,就非常简单了,从后往前枚举,查看当前能够买的价格为1的物品有多少,然后最后看剩余的钱是否能够买剩下的东西即可。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int a[N],t[N];
vector<int>vec[N];
int n,m,sum;
bool check(int x){
    memset(t,0,sizeof t);
    int mon=min(N-1,x),res=sum;
    for(int i=min(N-1,x);i;i--){
        if(mon>i)mon--;
        for(auto j:vec[i]){
            int buy=min(mon,a[j]-t[j]);
            mon-=buy,x-=buy,res-=buy;
            t[j]+=buy;
        }
    }
    return x>=res*2;
}
int main()
{

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),sum+=a[i];
    int x,y;
    for(int i=1;i<=m;i++)
        scanf("%d%d",&x,&y),vec[x].push_back(y);
    int l=0,r=1e6,mid,ans;
    while(r>=l){
        mid=l+r>>1;
        if(check(mid))
            r=mid-1,ans=mid;
        else
            l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

发布了554 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/104497300
今日推荐