int A, B, n = 26; cin >> A >> B; string S, T; cin >> S >> T; if (S == T) return cout << 0 << '\n', 0;
Vi a(2 * n + 5), b(2 * n + 5); For(i, 0, sz(S) - 1) { int t = rnd() % 100000; a[S[i] - 'a'] += t, b[T[i] - 'a'] += t; } For(i, 0, n - 1) a[i + n] = a[i]; int ff = 1; For(i, 0, n - 1) if (!b[i]) ff = 0; if (ff) return cout << "-1\n", 0;
auto fd = [&](int z) { For(i, 0, n - 1) if (b[i] == z) return i; return-1; };
auto solve = [&](auto r, int k) { V<hzy> vec; For(i, 0, n - 1) if (r[i]) { int s = 0, j = i, g = 0; for (; j < n; j++) { s += r[j]; if ((g = fd(s)) != -1) break; } if (j == n) return Inf; vec.pb({ i, j, g - k }), i = j; } For(i, 1, sz(vec) - 1) while (vec[i].z < vec[i - 1].z) vec[i].z += 26; if (sz(vec) > 1 && vec.back().z > vec[0].z + 26) return Inf; int ans = Inf; For(_, -4, 4) { int sum = 0; for (auto x : vec) { int w = x.z + _ * 26; if (w < x.l) sum += (x.r - w) * B; elseif (w > x.r) sum += (w - x.l) * A; else sum += (w - x.l) * A + (x.r - w) * B; } ans = min(ans, sum); } return ans; };
int ans = Inf; For(i, 0, n - 1) ans = min(ans, solve(a.begin() + i, i)); cout << (ans == Inf ? -1 : ans) << '\n'; }
D
给定一个正 n 边形,要用 n−3 条弦把它划分为 n−2 个三角形,求有一个面积严格大于其他三角形的三角形的方案数。
n≤444 。
笑点解析:O(n4) 。
三角形大小没什么结论,直接暴力跑出所有三角形的面积,离散化一下。
枚举最大三角形的大小,然后相当于分割成了三个部分,每个部分是经典 dp,设 fi 表示还有 i 个点的方案,然后去枚举中间选哪个点组成三角形,然后划分成两个子问题,转移就是一个卷积。
暴力做就是 O(n4),然后加亿点卡常就可以通过。
急宝没过,急死了 /cf。
E
有 2n 个点,第 i 个点坐标为 (i,0),你要进行一个匹配,匹配上的点用边连上,要求连边不交。