Loading

题解:[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;
}
posted @ 2024-10-20 08:51  Anins  阅读(19)  评论(0)    收藏  举报  来源