



🏰《金币分配大作战》
一、🎮 故事背景
1、小 A 有 2n 件宝物 💎
有两个买家:
👦 小 B:第 i 件愿意出价
b[i]👧 小 C:第 i 件愿意出价
c[i]
2、🎯 任务
👉 每个人必须买 n 件
👉 目标:
💰 总收入最大!
二、🧠 认清问题本质
1、很多同学会想:
❌ "枚举谁买哪件?" → 爆炸(2ⁿ)
我们要换一个思路:
2、💡 核心转化(关键突破🔥)
(1)👉 先假设:所有东西都卖给小 B
总收入 = 所有 b[i] 之和
(2)然后再想:
👉 如果某件给小 C,会怎样?
变化量 = c[i] - b[i]
(3)🧠 关键理解
| 情况 | 含义 |
|---|---|
| c[i] > b[i] | 给 C 更赚 |
| c[i] < b[i] | 给 B 更赚 |
(4)👉 问题变成:
从 2n 件中选 n 件给 C,让"增加的钱最多"
三、🧩 模型识别(竞赛思维)
(1)这一步非常关键!!
👉 本质是:
从一堆数中选 n 个最大的
(2)其中:
d[i] = c[i] - b[i]
四、🪜 完整解题步骤
✅ Step 1:全部给 B
ans += b[i];
✅ Step 2:计算"差值"
d[i] = c[i] - b[i];
👉 表示:改给 C 多赚多少
✅ Step 3:排序
sort(d);
👉 从小到大排序
✅ Step 4:选最大的 n 个
选最后 n 个
👉 因为它们"最值钱"
✅ Step 5:加到答案
ans += d[i];
五、🧠 为什么这样一定最优?
(1)👉 这是贪心策略
我们每次选择:
当前"最赚"的调整
(2)🔥 关键结论
👉 不需要考虑组合!
因为:
每件物品的收益是"独立的"
六、🧪 举个例子帮助理解
假设:
b: 1 3 5 6
c: 2 4 6 7
👉 Step1:全给 B
总 = 1+3+5+6 = 15
👉 Step2:差值
d: 1 1 1 1
👉 Step3:选2个最大
+1 +1
👉 最终答案
15 + 2 = 17
七、💻 参考代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<long long> b(2*n), c(2*n), d(2*n);
long long ans = 0;
// 输入
for (int i = 0; i < 2*n; i++) cin >> b[i];
for (int i = 0; i < 2*n; i++) cin >> c[i];
// Step1 + Step2
for (int i = 0; i < 2*n; i++) {
ans += b[i]; // 全给 B
d[i] = c[i] - b[i]; // 差值
}
// Step3
sort(d.begin(), d.end());
// Step4 + Step5
for (int i = n; i < 2*n; i++) {
ans += d[i]; // 选最大的 n 个
}
cout << ans << endl;
return 0;
}
八、🎯 知识点总结:
这题非常经典,背后是👇
🧠 ① 转化思想(最核心🔥)
👉 "选择问题" → "差值排序问题"
🧠 ② 贪心策略
👉 每次选最优(差值最大)
🧠 ③ 排序应用
👉 选前 n / 后 n