ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #727 (Div. 2)

2021-06-21 22:34:48  阅读:220  来源: 互联网

标签:int sum Codeforces long 727 second ans Div first


\(\sf D-PriceFixed\)

题目

简要题意

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

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

数据范围与提示

\(n\le 1e5,\ 1\le a_i,b_i\le 10^{14}\)。

解法

#1. \(\text{Two Pointers}\)

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

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

#2. \(\text{Binary Search}\)

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

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

时间复杂度 \(\mathcal O(n\log 10^{14})\)。

代码

#1. \(\text{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,'\n');
	return 0;
} 

#2. \(\text{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 << "\n";
}

标签:int,sum,Codeforces,long,727,second,ans,Div,first
来源: https://www.cnblogs.com/AWhiteWall/p/14916158.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有