微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Codeforces Round # 560 (Div. 3) F2. Microtransactions (complicated version) (二分)

题目链接http://codeforces.com/contest/1165/problem/F2

题意:n种物品需要购买,每种物品需要购买a[i]件,每件物品价格为2bourle,有m次优惠活动(di,ti):第di天物品ti价值优惠为1bourle

每天可以得到1bourle,求买完所有物品的最少天数。

思路:设所有物品数量为cnt,最少天数一定在[cnt,2 * cnt]之间,因为获得的物品数目随天数是递增的,所以二分找最优解

分享图片

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#define rep(i,s,e) for(int i = s; i < e; ++i)
#define lson l,m,rt << 1
#define rson m + 1,r,rt << 1 | 1
#define P pair<int,int>
#define INF 0x3f3f3f3f
#define Mod 998244353
using namespace std;
typedef long long ll;
static const int N = 1005;
static const int MAX_N = 2e5 + 5;
int a[MAX_N],b[MAX_N];
vector<int>vec[MAX_N << 1];
int n;
bool judge(int x,int cnt,vector<int>vec[]){
    int day = x;    //花费天数(即可花费的bourle,因为每天可获得1bourle)
    for(int i = 1; i <= n; ++i) b[i] = a[i];
    int cur = 0;
    for(int i = x; i >= 1; --i){    //x天的优惠活动
        for(int j = 0; j < vec[i].size(); ++j){
            int t = vec[i][j];
            while(b[t] && day){     //尽可能多的在优惠中购买物品
                --b[t];
                --cnt;  //物品总数
                --day;  //bourle数量减少
            }
        }
        while(day >= i) ++cur,--day;   //borcle数目不能超过天数,多余部分只能用于未参与优惠的物品(这里条件控制的比较好,用if也行)
    }
    return cur >= 2 * cnt;  //未参与优惠的物品需2bourle
}
void solve(){
//    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
    //ios::sync_with_stdio(false);
    int m;
    while(scanf("%d%d",&n,&m) != EOF){
        int cnt = 0;
        for(int i = 0; i < (MAX_N << 1); ++i) vec[i].clear();
        for(int i = 1; i <= n; ++i){
            scanf("%d",&a[i]);
            cnt += a[i];
        }
        for(int i = 0; i < m; ++i){
            int u,v;
            scanf("%d%d",&u,&v);
            vec[u].push_back(v);
        }
        int l = cnt,r = cnt << 1;
        int ans = 0;
        while(l <= r){
            int m = l + r >> 1;
            if(judge(m,cnt,vec)){
                r = m - 1;
                ans = m;
            }
            else l = m + 1;
        }
        printf("%d\n",ans);
    }
}
int main() {
    solve();
    return 0;
}
View Code

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。