Solution - Median Sum
其它题不是很写得动了跑来写一下这个题,还是挺有趣的。
给定由 个正整数 组成的可重集合,求出它的非空子集的和的中位数。
设 。
首先是对于任意一个子集,设其和为 ,我们将其取反,就是选的改成不选,不选的改成选,那么前后子集之和是 ,改之后的子集和就是 ,不妨 ,那么一定有 。如果这时候把空集也算进去(方便计算,而中位数取中间更大的那个即可,也就是从小到大排序之后位于 位置的数),和 的子集个数就一定为 。于是我们只需要找到第一个 的子集和就好了。
于是就转化成了一个存在性问题。因为这个 ,考虑直接设 表示前 个数的和能否是 。转移不表,但是这样时空复杂度都是 的。滚动数组空间可以优化到 ,至于转移可以发现就是一堆或的操作,用 bitset 维护,为 ,就可以过了。
namespace liuzimingc {
const int N = 2e3 + 5, M = 4e6 + 5;
int n, a[N], sum;
bitset<M> f[2];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i], sum += a[i];
f[0][0] = true;
for (int i = 1; i <= n; i++) {
f[i & 1] = f[i - 1 & 1]; // 不选第 i 个
f[i & 1] |= f[i - 1 & 1] << a[i]; // 选第 i 个
}
for (int i = sum + 1 >> 1; ; i++) // >= sum / 2,隐含向上取整
if (f[n & 1][i]) return cout << i << endl, 0;
return 0;
}
} // namespace liuzimingc
附赠一下,比如今天的 Eighty seven,乍一看以为是什么高级东西,但是发现维护的东西跟上面这个都是一样的,也这么做就好了。
Posted by liuzimingc
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律