[ABC400G] Patisserie ABC 3
Statement
给定正整数 \(n,k\) 和 \(n\) 个三元组 \((x_i,y_i,z_i)\)。
现要选出 \(k\) 个二元组 \((a_i,b_i)\),满足每个位置只能出现一次,并要求最大化:
\[\sum_{i=1}^k\max\{x_{a_i}+x_{b_i},y_{a_i}+y_{b_i},z_{a_i}+z_{b_i}\}\]
输出这个最大值。
Data range:\(T\) 组多测,\(\sum n\le 10^5\),\(2k\le n\),\(0\le x_i,y_i,z_i\le 10^9\)。
Solution
首先你考虑每个数对答案的贡献。你发现每种数(指 \(x,y,z\))的贡献都是成对的,所以肯定要求数量都是偶数。
而你发现偶数是充要的(两两配对就行,如果实际上不是这种数产生贡献那也肯定不是最优解),那么问题转化成了:
对于每个 \(i\) 可以选 \(x_i\)、选 \(y_i\)、选 \(z_i\) 或什么都不选,要求一共选 \(2k\) 个,且每种数都要选偶数个,求最大和。
这里就有了一个 \(\mathcal O(nk)\) 的做法了,就是 dp 记一下前 \(i\) 个里选了 \(j\) 个,\(x,y,z\) 分别有奇数/偶数个的最大和。
当然这是过不了的,考虑优化。
你发现偶数这个限制很松,即使不符合稍微调一下也能符合。
那你考虑按 \(\max\{x_i,y_i,z_i\}\) 从大到小排序。
然后会有一个结论:最终方案中,前 \(2k\) 个里面最多有两个不选(被调整成后面的至多两个,注意前面的选了并不一定是最大的那个)。
证明:
假设前面的有三个没选,那么对应的后面会选了三个。
我们称一个前面的没选的 \(x_i\) 最大的位置为 \(\texttt X\) 类,\(\texttt Y,\texttt Z\) 类同理;后面的选了 \(x_i\) 的位置为 \(\texttt x\) 类,\(\texttt y,\texttt z\) 类同理。
那么:
- 显然不可能同时出现 \(\texttt X,\texttt x\) 类,因为可以直接替换掉,其他的同理。
- 也不可能同时出现两个 \(\texttt X\) 类和两个 \(\texttt y\) 类:也可以直接替换。
之后简单分讨一下就可以证明该命题。
那么接下来就简单了:对前 \(2k\) 个和后面 \((n-2k)\) 个分别 dp,那么「选了几个」的维度就被压缩到了 \(3\) 的长度(对于前面可以记不选了几个),那么 dp 的复杂度就降到了 \(\mathcal O(n)\)。
于是就在 \(\mathcal O(n\log n)\) 的时间复杂度内解决了本题,瓶颈在于排序。
- 本题只有 \(x,y,z\) 三维,但实际上可以扩展到 \(m\) 维的情况。此时可以证明前面至多 \((m-1)\) 个被替换成后面的,所以可以在 \(\mathcal O(n\log n+nm^22^m)\) 的时间复杂度内解决(注意转移带一个 \(m\))。
Code
32ms/14MB
截至现在它还是并列最优解。注意到有个 31ms
的代码与此代码编辑距离为 \(0\)。小朋友素质无敌了。
1 | // Author: YE Minghan |