给定两个序列,\(\{a_i\}\) 和 \(\{b_i\}\)。要求选出 \(\{i_k\}\) 和 \(\{j_k\}\),满足:
求 \(\min\left(\displaystyle\sum_{p=1}^k (a_{i_p}+b_{j_p})\right)\)。
我们先看一眼数据范围——\(n\le 2200\),这暗示我们时间复杂度应该会劣于\(O(n^2)\)。
我们考虑一个图,满足:
不难看出,在该图中,当流量为 \(k\) 时,最小费用刚好为我们所求的 \(\min\left(\displaystyle\sum_{p=1}^k (a_{i_p}+b_{j_p})\right)\)。随便分析一下时间复杂度,为 \(O(nm)\),足以通过此题。
核心代码如下(用到了 AtCoder 的模板库):
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> k;
mcf_graph<ll, ll> graph(n + 2);
for (int i = 1; i <= n; i++) {
int temp;
cin >> temp;
graph.add_edge(0, i, 1, temp);
if (i < n) graph.add_edge(i, i + 1, k, 0);
}
for (int i = 1; i <= n; i++) {
int temp;
cin >> temp;
graph.add_edge(i, n + 1, 1, temp);
}
pair<long long, long long> ans = graph.flow(0, n + 1, k);
cout << ans.second << endl;
return 0;
}
题解 CF802N 【April Fools' Problem (medium)】
原文:https://www.cnblogs.com/David-H-Devs/p/14174992.html