题解:[ABC376C] Prepare Another Box
[ABC376C] Prepare Another Box
题意:
给定 \(N\) 个物品,第 \(i\) 个的体积为 \(a_i\),以及 \(N-1\) 个箱子,第 \(i\) 个的体积为 \(b_i\),让我们添加一个箱子,使得每个物品都能找到一个不小于它的箱子,求添加箱子的体积的最小值,无解输出 \(-1\)。
思路:
每次给当前体积最大的物品分配当前体积最大的箱子,如果该箱子体积小于当前物品,则添加一个与物品体积相同的箱子,若需要添加两个及以上箱子,则无解。
正确性证明:
-
为什么用最大箱子?
若可以用非最大箱子,那么最大箱子就留给了其他物品用,这是等价的,并不会对后面的箱子选择产生影响。
-
为什么最大箱子不满足时创建一个箱子?
若当前最大箱子不满足当前最大物品,那么可以取之前的比当前大的箱子来满足当前物品,但这样就没有箱子满足之前箱子对应的物品,需要为那个物品创建箱子,显然不如为当前物品创建箱子更优。
关于正确性的其他问题读者可以自行思考。
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n, a[200005], b[200005];
bool cmp(ll x, ll y) {
return x>y;
}
int main() {
scanf("%lld", &n);
for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
for(int i=1; i<n; i++) scanf("%lld", &b[i]);
sort(a+1, a+n+1, cmp);
sort(b+1, b+n, cmp);
ll ans=0;
for(int ai=1, bi=1; ai<=n&&bi<n; ai++) {
if(b[bi]<a[ai]) {
if(ans>0) { //之前已经创建过箱子,无解
ans=-1;
break;
} else ans=a[ai]; //存储箱子体积
} else bi++;
}
if(ans==0) ans=a[n]; //前n-1个都满足,那么就为第n个创建箱子
printf("%lld", ans);
return 0;
}

浙公网安备 33010602011771号