問題
https://codeforces.com/contest/1861/problem/E (diff 2300)
以上
以下の整数からなる長さ
の数列
について、
の美しさを以下の通り定める。
から
から
の値が丁度一回ずつ出現する
の連続部分列を、共通区間が存在しないように
個取り出せるとする
としてありうる最大値
以上
以下の整数からなる長さ
の数列
全ての美しさの総和
を求めよ。
https://codeforces.com/contest/1861/problem/E (diff 2300)
以上
以下の整数からなる長さ
の数列
について、
の美しさを以下の通り定める。
以上
以下の整数からなる長さ
の数列
全ての美しさの総和
を求めよ。
https://codeforces.com/contest/1860/problem/E (2400diff)
文字列が与えられる。
内にカーソルが一つあることを考える。カーソルは文字と文字の間にある。あなたはカーソルに対して以下の操作を行うことができる
個のクエリが与えられる。
https://codeforces.com/contest/1886/problem/E (2400diff)
人のプログラマーがいて、
人目の耐久力は
である。
個のプロジェクトがあって、
個目のプロジェクトの難易度は
である。
あなたは、各プロジェクトにプログラマーを割り当てる。以下の条件を全て満たす割当てが存在するか判定し、存在する場合はそのような割当てを一つ求めよ。
https://codeforces.com/contest/1895/problem/F (diff: 2600)
が与えられる。以下の条件を満たす長さ
の非負整数列
を数え上げよ。
https://codeforces.com/contest/1901/problem/E (2200diff)
木が与えられる。各頂点には整数
が書き込まれている。
あなたは木に対して回以上以下の操作を行う。
全ての操作を終えた後、木が以下のように変化する
残った頂点に書き込まれている値の総和(以下スコアと呼ぶ)を最大化せよ
https://codeforces.com/contest/1902/problem/F (2400diff)
頂点からなる木があって、各頂点
には整数
が書き込まれている。
個のクエリ
に答えよ
制約:
https://codeforces.com/contest/1913/problem/E (2400diff)
行
列の01行列
が与えられる。また、長さがそれぞれ
の数列
が与えられる。
あなたの目標はのいくつかのマスを反転することで、
行目の
の数を
個、
列目の
の数を
にすることである。
目標を達成することが可能なら、反転するマスの最小個数を、不可能ならそのことを報告せよ。
制約
が明らかに必要。
最小費用流の問題に帰着させる。各マスに0か1を割り当てることを考える。
負コストがあるので、初回のポテンシャル計算にはベルマンフォードを使う。最初ネットワークがDAGなので、dpをしても良い。
#include <bits/stdc++.h> #include "Src/Template/IOSetting.hpp" #include "Src/Graph/Flow/SuccessiveShortestPath.hpp" using namespace zawa; int main() { SetFastIO(); int n, m; std::cin >> n >> m; std::vector s(n, std::vector<int>(m)); for (auto& v : s) for (auto& x : v) std::cin >> x; std::vector<int> a(n), b(m); for (auto& x : a) std::cin >> x; for (auto& x : b) std::cin >> x; int sum{std::reduce(a.begin(), a.end(), 0)}; if (sum != std::reduce(b.begin(), b.end(), 0)) { std::cout << -1 << '\n'; return 0; } SuccessiveShortestPath<int, int> mcf(n + m + 2); int source{n + m}, sink{source + 1}; for (int i{} ; i < n ; i++) { mcf.addEdge(source, i, a[i], 0); } for (int i{} ; i < m ; i++) { mcf.addEdge(n + i, sink, b[i], 0); } int ans{}; for (int i{} ; i < n ; i++) { for (int j{} ; j < m ; j++) { if (s[i][j] == 0) { mcf.addEdge(i, n + j, 1, 1); } else if (s[i][j] == 1) { ans++; mcf.addEdge(i, n + j, 1, -1); } else { assert(false); } } } mcf.dagdp(source, sink); mcf.updatePotential(); int flow{mcf.maxflow(source, sink)}; assert(flow <= sum); if (flow < sum) { std::cout << -1 << '\n'; return 0; } ans += mcf.minCost(); std::cout << ans << '\n'; }
自分のMCFはACLより遅いが、ベルマンフォードやDAG上のDPでポテンシャルが計算できるのが強み(自慢)
バチャ中はE問題を開くことが無かった。
自分にとってはDよりEの方が解きやすそうに見えた。
しかし、Dが解けていないなかでEのフローを信じて詰めれたかと言われると、かなり自信が無い。Dを解かないと始まらないな。