AtCoder Beginner Contest 236 题解

A,B,C 题过水,不作赘述,我的 Atcoder 号是 Complex ,需要代码可以去找找。

DDance

2n 个人按每组两人分成 n 组,第 i 人和第 j 人同一组会产生 Ai,j 的贡献,求 n 组贡献值的异或和最大值。

1n8

评分 1190 ,其实真实难度完全达不到这个分的难度。

注意到数据很小,提示我们搜索也许可做,直接枚举排列然后按顺序两个人分一组,复杂度是 O((2n)!) ,肯定过不去,又注意到有很多重复计算的情况,选择时给人打标记,如果当前人已经有标记,直接去下一层,否则枚举比当前的人编号大的且未被分组的人进行搜索,每次人数减少 2 ,最大复杂度是 1513...1 ,可过。

EAverage and Median

给定 n 个数的序列 A ,相邻的两个数里面至少要有一个被选出来,求选出来的数字构成的新序列的平均值和中位数最大值,设新序列长度是 L ,其中中位数的定义为该序列中从小到大数第 L/2 大的数字。

2n100000 , 1Ai109

评分 1900 ,是一道质量很高的题目。

其实见到平均数和中位数的常用套路就是二分答案,这题第一步就是二分这两个数字。

注意到一个序列的平均数如果大于 K ,那么序列中每个数减去 K 之后,序列和一定 >0 ,利用这个性质,我们直接在二分答案判定时,对 A 中的数字都减去当前判定的答案 mid ,此时在满足题目要求的选数规则的前提下,如果能选出一个和 >0 的子序列,那么这个平均数就是合法的 ,可以尝试更大的数字,那么怎么找这个子序列呢?其实只需要能选出的最大子序列和 >0 就行了,用一个线性 DP 解决。

f[i][1/0] 表示在前 i 个数里面选择,且 第 i 个数保证是选/不选的最大子序列和。

那么根据题意,相邻的数必须至少选一个,方程很好写:

f[i][1]=max(f[i1][0],f[i1][1])+a[i]mid ,当前已经选,上一个选不选都可以

f[i][0]=f[i1][1] ,当前没选,上一个必须选

最后判断 max(f[n][1],f[n][0]) 是否是 0 即可(注意取等!)。

那么中位数呢?方法是类似的,中位数一定是原序列中的某一个数,于是重新用一个数组复制一次 A 序列,然后从小到大排序(不能直接对 A 排序,这样会打乱相邻数位置),然后二分下标即可,对 当前判断答案的数字的权值设为 1 ,其余设为 1 ,求最大子序列和是否 >0 即可(注意此处不取等)。

时间复杂度 O(nlogn)

posted @   Constant1227  阅读(151)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示