题解:P14635 [NOIP2025] 糖果店
lailai0916 · · 题解
题意简述
给定
解题思路
考场思路。
我们可以将每种糖果拆分为两类 套装:
- 单颗装:售价
a_i=x_i 元,限购1 组; - 两颗装:售价
b_i=x_i+y_i 元,不限组数。
由于两类套装的相互独立,可以将
显然花费随着糖果数量增加 单调递增,我们可以对购买数量
计算购买
考虑两类套装的最小花费:
- 单颗装:选择
a_i 最小的前q 种,即a_i 的前缀和s_q ; - 两颗装:选择
p 组b_i 最小的,即pb_1 。
枚举两颗装组数
关于
时间复杂度为 __int128。
半小时过 T1,罚坐四小时。
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int N=100005;
ll a[N],b[N];
ll n,m;
bool check(ll k)
{
__int128 mn=inf;
for(ll p=max(k-n+1>>1,0ll);p<=k>>1;p++)
{
mn=min(mn,__int128(p)*b[1]+a[k-p*2]);
}
return mn>m;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i];
b[i]+=a[i];
}
sort(a+1,a+n+1);
sort(b+1,b+n+1);
for(int i=1;i<=n;i++)a[i]+=a[i-1];
ll l=0,r=inf;
while(l<r)
{
ll mid=l+r>>1;
if(check(mid))r=mid;
else l=mid+1;
}
cout<<l-1<<'\n';
return 0;
}