Codeforces Round #560 (Div. 3) F2. Microtransactions (hard version)

链接

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

题意

需要购买 n n n 个物品,每个物品需要 k i k_i ki 个。

每个物品原价为 2 2 2 元,打折则为 1 1 1 元。

现在有 m m m 个打折信息,每个信息代表某个物品在某日打折。

每天能获得 1 1 1 元,求买完所有需要的物品的天数。

思路

贪心策略:若该物品为最后一次打折日,则购买。

二分天数。

代码

#include <bits/stdc++.h>
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(),(x).end()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define FI first
#define SE second
using namespace std;
typedef double DB;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;
//head
const int N=2e5+5;
int n,m,k[N],sum;
bool st[N];
PII o[N];
bool check(int x) {
    for(int i=1;i<=n;i++) st[i]=false;
    int tot=0,pre=0x3f3f3f3f;
    for(int i=m;i>=1;i--) {
        if(o[i].FI>x||st[o[i].SE]) continue;
        pre=min(pre,o[i].FI);
        int t=min(pre,k[o[i].SE]);
        tot+=t;
        st[o[i].SE]=true;
        pre-=t;
    }
    return tot+(sum-tot)*2<=x;
}
int solve() {
    sort(o+1,o+1+m);
    int l=0,r=sum*2;
    while(l<r) {
        int mid=l+r>>1;
        if(check(mid)) r=mid;
        else l=mid+1;
    }
    return l;
}
int main() {
    //freopen("E:/OneDrive/IO/in.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>k[i],sum+=k[i];
    for(int i=1;i<=m;i++) cin>>o[i].FI>>o[i].SE;
    cout<<solve()<<'\n';
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值