题解 [ARC121D] 1 or 2

诈骗题,竟然评到了 2784 的惊人高分(快到红了),来补个题解。

题意:有两个可重集 A,BB 初始为 。每次从 A 中删除一个或两个数,并将它们的和加入 B 中,重复操作直到 A=。最小化 B 的极差。

1|A|5×103

如果每次必须删除两个数,显然最小与最大、次小与次大配对是最优的,可以用交换法证明。观察到删除一个数的操作等价于删除 0 和那个数。因此枚举有多少次删除一个数的操作,补充那么多个 0 之后跑刚刚的贪心即可。

容易做到 Θ(n2),但我懒得做到,所以写了一个 Θ(n2logn)

//By: OIer rui_er
#include <bits/stdc++.h>
#define rep(x,y,z) for(ll x=(y);x<=(z);x++)
#define per(x,y,z) for(ll x=(y);x>=(z);x--)
#define debug(format...) fprintf(stderr, format)
#define fileIO(s) do{freopen(s".in","r",stdin);freopen(s".out","w",stdout);}while(false)
using namespace std;
typedef long long ll;
const ll N = 1e4+5, inf = 0x3f3f3f3f3f3f3f3fll;

ll n, a[N], b[N], ans = inf;
template<typename T> void chkmin(T& x, T y) {if(x > y) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}

int main() {
	scanf("%lld", &n);
	rep(i, 1, n) scanf("%lld", &a[i]);
	rep(i, 0, n) {
		ll L = 1, R = n + i;
		if((R - L + 1) & 1) continue;
		rep(j, 1, n) b[j] = a[j];
		rep(j, n+1, n+i) b[j] = 0;
		sort(b+1, b+1+n+i);
		ll mn = inf, mx = -inf;
		while(L < R) {
			chkmin(mn, b[L] + b[R]);
			chkmax(mx, b[L] + b[R]);
			++L; --R;
		}
		chkmin(ans, mx - mn);
	}
	printf("%lld\n", ans);
	return 0;
}
posted @   rui_er  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示