結果
| 問題 |
No.1288 yuki collection
|
| コンテスト | |
| ユーザー |
siman
|
| 提出日時 | 2022-03-26 11:58:36 |
| 言語 | C++17(clang) (17.0.6 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,177 bytes |
| コンパイル時間 | 3,910 ms |
| コンパイル使用メモリ | 148,940 KB |
| 実行使用メモリ | 73,984 KB |
| 最終ジャッジ日時 | 2024-10-15 03:56:29 |
| 合計ジャッジ時間 | 49,233 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 7 WA * 25 TLE * 2 -- * 6 |
ソースコード
#include <cassert>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <climits>
#include <map>
#include <queue>
#include <set>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int MAX_V = 2010;
const ll INF = LLONG_MAX;
typedef pair<ll, int> P;
struct Edge {
int to;
ll cap;
ll cost;
int rev;
Edge(int to = -1, ll cap = -1, ll cost = -1, int rev = -1) {
this->to = to;
this->cap = cap;
this->cost = cost;
this->rev = rev;
}
};
class MinCostFlow {
public:
int V;
ll h[MAX_V];
ll dist[MAX_V];
int prevv[MAX_V];
int preve[MAX_V];
vector <Edge> G[MAX_V];
MinCostFlow(int V) {
this->V = V;
}
void add_edge(int from, int to, ll cap, ll cost) {
G[from].push_back(Edge(to, cap, cost, G[to].size()));
G[to].push_back(Edge(from, 0, -cost, G[from].size() - 1));
}
ll min_cost_flow(int s, int t, ll flow_limit) {
ll f = 0;
ll totalCost = 0;
fill(h, h + MAX_V, 0);
while (f < flow_limit) {
fprintf(stderr, "f: %lld, limit: %lld\n", f, flow_limit);
priority_queue<P, vector<P>, greater<P>> pque;
fill(dist, dist + V, INF);
dist[s] = 0;
pque.push(P(0, s));
while (!pque.empty()) {
P p = pque.top();
pque.pop();
int v = p.second;
if (dist[v] < p.first) continue;
for (int i = 0; i < (int) G[v].size(); ++i) {
Edge *edge = &G[v][i];
if (edge->cap <= 0) continue;
ll cost = edge->cost + h[v] - h[edge->to];
if (dist[edge->to] - dist[v] > cost) {
dist[edge->to] = dist[v] + cost;
prevv[edge->to] = v;
preve[edge->to] = i;
pque.push(P(dist[edge->to], edge->to));
}
}
}
if (dist[t] == INF) {
return -1;
}
for (int v = 0; v < V; ++v) {
h[v] += dist[v];
}
ll c = flow_limit - f;
for (int v = t; v != s; v = prevv[v]) {
c = min(c, G[prevv[v]][preve[v]].cap);
}
f += c;
totalCost += c * h[t];
// fprintf(stderr, "h[s]: %d, h[t]: %d, cost: %d, prev_cost: %d\n", h[s], h[t], cost, prev_cost);
for (int v = t; v != s; v = prevv[v]) {
Edge *edge = &G[prevv[v]][preve[v]];
edge->cap -= c;
G[v][edge->rev].cap += c;
}
}
return totalCost;
}
};
int main() {
int N;
cin >> N;
string S;
cin >> S;
vector<ll> V(N);
for (int i = 0; i < N; ++i) {
cin >> V[i];
}
map<char, int> counter;
map<char, int> c_counter;
int ch_nums[27];
memset(ch_nums, 0, sizeof(ch_nums));
for (int i = 0; i < N; ++i) {
char s = S[i];
c_counter[s]++;
ch_nums[i] = c_counter[s];
if (s == 'y') {
counter[s]++;
} else if (s == 'u') {
counter[s] = min(counter['y'], c_counter[s]);
} else if (s == 'k') {
counter[s] = min(counter['u'], c_counter[s]);
} else if (s == 'i') {
counter[s] = min(counter['k'], c_counter[s]);
}
}
MinCostFlow mcf(N + 2);
int from = N;
int to = N + 1;
ll GETA = 1000000000;
for (int i = 0; i < N; ++i) {
char s = S[i];
char target;
for (int j = i + 1; j < N; ++j) {
if (S[j] == s) {
mcf.add_edge(i, j, N + 1, 0);
}
}
if (s == 'y') {
mcf.add_edge(from, i, 1, 0);
for (int j = i + 1; j < N; ++j) {
if (S[j] != 'u') continue;
mcf.add_edge(i, j, 1, GETA - V[i]);
break;
}
} else if (s == 'u') {
for (int j = i + 1; j < N; ++j) {
if (S[j] != 'k') continue;
mcf.add_edge(i, j, 1, GETA - V[i]);
break;
}
} else if (s == 'k') {
for (int j = i + 1; j < N; ++j) {
if (S[j] != 'i') continue;
mcf.add_edge(i, j, 1, GETA - V[i]);
break;
}
} else if (s == 'i') {
mcf.add_edge(i, to, 1, GETA - V[i]);
}
}
int flow = counter['i'];
ll res = mcf.min_cost_flow(from, to, flow);
cout << GETA * flow * 4 - res << endl;
return 0;
}
siman