• Codeforces Round #727 (Div. 2)


    (sf D-PriceFixed)

    题目

    简要题意

    在一个折扣店有 (n) 种商品,每种商品的价格都是 (2)。对于商品 (i) 你需要买 (a_i) 个,而如果在买商品 (i) 之前你购买的商品数量(指所有种类的商品数量)大于等于 (b_i),你就可以半价购买商品 (i)

    请合理安排商品购买顺序使得完成购买任务所花费的钱最少。

    数据范围与提示

    (nle 1e5, 1le a_i,b_ile 10^{14})

    解法

    #1. ( ext{Two Pointers})

    贪心地想,在当前 (b_i) 最小的商品不能半价时买 (b_i) 最大的商品一定不会更劣。

    所以可以直接将商品按 (b_i) 排序,用两个指针 (l,r) 往中间遍历。我们用牺牲 (r) 换取 (l) 的半价。

    #2. ( ext{Binary Search})

    我们还是将商品按 (b_i) 排序。那么任务就是最小化全价商品数。

    二分全价商品数 ( m mid)。检验是否合法就是按排序顺序遍历商品,购买能够买到的所有半价商品数记其为 (w),如果满足 ( ext{mid}+wge sum a_i) 就合法。

    时间复杂度 (mathcal O(nlog 10^{14}))

    代码

    #1. ( ext{Two Pointers})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i,_l,_r) for(signed i=(_l),_end=(_r);i<=_end;++i)
    #define print(x,y) write(x),putchar(y) 
    
    template <class T> inline T read(const T sample) {
        T x=0; int f=1; char s;
        while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
        while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
        return x*f;
    }
    template <class T> inline void write(const T x) {
        if(x<0) return (void) (putchar('-'),write(-x));
        if(x>9) write(x/10);
        putchar(x%10^48);
    }
    
    typedef long long ll;
    typedef pair <ll,ll> Pair;
    
    const int maxn=1e5+5;
    
    int n;
    Pair s[maxn];
    
    int main() {
    	n=read(9);
    	rep(i,1,n) s[i].second=read(9ll),s[i].first=read(9ll);
    	sort(s+1,s+n+1);
    	ll ans=0,sum=0; int l=1,r=n;
    	while(l<r) {
    		if(sum<s[l].first) {
    			if(s[r].second>s[l].first-sum) {
    				s[r].second-=s[l].first-sum;
    				ans+=(s[l].first-sum)*2,sum=s[l].first;
    			}
    			else {
    				sum+=s[r].second;
    				ans+=s[r].second*2; s[r].second=0,--r;
    			}
    			if(sum>=s[l].first) {
    				sum+=s[l].second,ans+=s[l].second,++l;
    			}
    		}
    		else sum+=s[l].second,ans+=s[l].second,++l;
    	}
    	if(l==r) {
    		if(sum>=s[l].first) ans+=s[l].second;
    		else {
    			if(s[l].second>s[l].first-sum)
    				ans+=(s[l].first-sum)*2+s[l].second-s[l].first+sum;
    			else ans+=s[l].second*2;
    		}
    	}
    	print(ans,'
    ');
    	return 0;
    } 
    

    #2. ( ext{Binary Search})

    #include <bits/stdc++.h>
    using namespace std;
    
    bool cmp(pair<long long, long long> &x, pair<long long, long long> &y) {
        return x.second < y.second;
    }
    
    int main() {
        ios_base::sync_with_stdio(false);
        cin.tie(nullptr);
    
        int n; cin >> n;
        vector<pair<long long, long long>> in(n);
        for(int i = 0; i < n; i++) {
            cin >> in[i].first >> in[i].second;
        }
        sort(in.begin(), in.end(), cmp);
    
        long long lo = 0LL, hi = 1e15, tot = 0LL;
        for(int i = 0; i < n; i++) {
            tot += in[i].first;
        }
        for(int j = 0; j < 60; j++) {
            long long tst = (lo + hi) / 2;
            long long soFar = tst;
            for(int i = 0; i < n; i++) {
                if(soFar >= in[i].second)
                    soFar += in[i].first;
            }
            if(soFar >= tot) {
                hi = tst;
            }
            else lo = tst + 1;
        }
        cout << tot + lo << "
    ";
    }
    
  • 相关阅读:
    Vue 自定义指令
    微信小程序 基础知识点整理
    32设计模式之单例
    Redis缓存穿透,缓存击穿,缓存雪崩
    Redis持久化之RDB和AOF
    Redis事务
    Mac下用Homebrew安装mongodb及遇到的问题解决
    mac下国内安装Homebrew教程
    Redis常用命令汇总及集群的配置
    redis.conf配置详解
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/14916158.html
Copyright © 2020-2023  润新知