移动端 Banners
CF 1728F - Fishermen 题解
686 字
3 分钟
CF 1728F - Fishermen 题解
Done
您已获得最佳的阅读体验!
题目地址:CF 1728F - Fishermen
这道题很难一眼看出所用算法,因此先从题目本身入手。
可以发现,当每个
所以先来处理
现在问题转化成了,让每一个
最后还需要处理一个要求:最小化 st 数组,如此可以优化时间复杂度到
#include <bits/stdc++.h>
#define N 1000010#define M 1000010
using namespace std;typedef long long ll;
struct Edge { int to, ne;} edges[M << 1];int h[N], idx = 0;int a[N], b[N];bool st[N];int match[N];vector<int> unq;map<int, int> discrete;int n;
void add(int a, int b) { idx++; edges[idx].to = b; edges[idx].ne = h[a]; h[a] = idx;}
bool hungary(int u) { for (int i = h[u]; ~i; i = edges[i].ne) { int j = edges[i].to; if (!st[j]) { st[j] = true; if (!match[j] || hungary(match[j])) { match[j] = u; return true; } } } return false;}
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
memset(h, -1, sizeof h);
cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i <= n; i++) { for (int k = 1; k <= n; k++) { unq.push_back(a[i] * k); // 处理倍数,预备去重 } } sort(unq.begin(), unq.end()); int cnt = unique(unq.begin(), unq.end()) - unq.begin(); // 去重,顺带升序排序 int disc = 0; for (int i = 0; i < cnt; i++) { // 离散化 discrete[unq[i]] = ++disc; b[disc] = unq[i]; // 去重前就已完成排序,直接赋值 } for (int i = 1; i <= n; i++) { for (int k = 1; k <= n; k++) { add(discrete[a[i] * k] + n, i); } } ll ans = 0; int res = 0; for (int i = 1; i <= cnt; i++) { if (hungary(i + n)) { // 优化 memset(st, false, sizeof st); res++; ans += b[i]; } if (res == n) break; // 总共匹配n个a } cout << ans << endl; return 0;}因为偷懒使用了
CF 1728F - Fishermen 题解
https://justpureh2o.cn/articles/40858/ 最后更新于 2024-08-06,距今已过 592 天
部分内容可能已过时
相关文章 智能推荐
1
CF 1404E - Bricks 题解
题解 2024-08-05
2
UVA10129 - Play On Words 题解
题解 2024-08-06
3
CF 126D - Fibonacci Sums 题解
题解 2024-10-31
4
CF 755D - PolandBall and Polygon 题解
题解 2024-11-27
5
P10935 - 银河 题解
题解 2024-09-01
随机文章 随机推荐