1 条题解
-
0
一、题目大意回顾
有 种颜色的手套,每种颜色 有 只左手手套、 只右手手套。 在完全看不见手套的前提下,随机从抽屉抽取手套。 一副合法配对定义为:同一种颜色 1 只左手 + 1 只右手。 要求求出最少抽取多少只手套,能保证一定存在至少 副不同颜色的配对。
本质是最坏情况构造 + 贪心极值问题: 我们先构造「最多能抽多少只,仍然凑不出 种不同配对」,答案就是这个数量 。
二、核心解题思想
本题采用逆向贪心思维: 不去直接求保证 对的最小数量, 而是先求最坏情况下,最多能拿多少只手套,最多只有 种不同颜色配对, 再在此基础上加 1,就是题目要求的答案。
设 ,代表允许最多存在 种不同颜色配对,我们构造极限最多手套数 ,最终答案 。
三、贪心策略逐层推导
1. 基础定义
对每种颜色 :
- :只拿单种手势(全左或全右)能拿的最大数量,此时完全无法形成任何配对;
- :剩下另一种手势的手套数量,这部分是后续可以补出来形成配对的余量。
2. 当 (不能有任何一对配对)
想要一只配对都凑不出来,最优最坏策略: 每种颜色只拿数量多的那一手,全部累加:
此时所有手套都是单左手或单右手,没有任何一副完整配对。
3. 当 (最多只能有 1 种颜色配对)
在 的基础上,我们可以额外多选一种颜色的全部余量 ,让这一种颜色可以形成配对,其余颜色仍无配对。 为了让总手套数最大,贪心选择** 最大**的那一个值加上去:
4. 当 (最多只能有 2 种颜色配对)
同理,在基础总和上,加上最大的两个 :
5. 推广到一般
想要最多只存在 种不同颜色配对:
- 先累加所有颜色的 ;
- 将所有 从大到小排序;
- 取前 个最大的 累加到总和;
- 此时得到的 就是最坏情况下不满足要求的最大手套数;
- 答案即为 。
四、正式算法步骤
- 多组测试用例输入,依次处理每组数据;
- 读入颜色数 、要求配对种数 ,令 ;
- 读入左手数组 、右手数组 ;
- 遍历每种颜色,计算 ,累加所有 得到基础和;
- 将 数组降序排序;
- 累加前 个最大的 到总和;
- 最终答案为总和 ,输出即可。
五、标准程序代码
#include <bits/stdc++.h> using namespace std; void test() { int n, k; cin >> n >> k; int m = k - 1; vector<int> l(n); for (int i = 0; i < n; i++) { cin >> l[i]; } vector<int> r(n); for (int i = 0; i < n; i++) { cin >> r[i]; } vector<int> a(n), b(n); long long y = 0; for (int i = 0; i < n; i++) { a[i] = max(l[i], r[i]); b[i] = min(l[i], r[i]); y += a[i]; } sort(b.begin(), b.end(), greater<>()); for (int i = 0; i < m; i++) { y += b[i]; } long long x = y + 1; cout << x << '\n'; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; for (int i = 0; i < t; i++) { test(); } return 0; }
- 1
信息
- ID
- 6757
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者