結果

問題 No.1288 yuki collection
コンテスト
ユーザー dayo ZOI
提出日時 2025-11-13 08:37:53
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 3,467 bytes
コンパイル時間 4,875 ms
コンパイル使用メモリ 320,644 KB
実行使用メモリ 7,720 KB
最終ジャッジ日時 2025-11-13 08:38:03
合計ジャッジ時間 8,492 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 35 WA * 5
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

//@yukicoder 1288

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
using vl = vector<ll>;
template <class T>
using vec = vector<T>;
template <class T>
using vv = vec<vec<T>>;
template <class T>
using vvv = vv<vec<T>>;
template <class T>
using minpq = priority_queue<T, vector<T>, greater<T>>;
#define rep(i, r) for (ll i = 0; i < (r); i++)
#define reps(i, l, r) for (ll i = (l); i < (r); i++)
#define rrep(i, l, r) for (ll i = (r)-1; i >= l; i--)
#define all(a) (a).begin(), (a).end()
#define sz(a) (ll)(a).size()
template <typename T>
bool chmax(T& a, const T& b) {
  return a < b ? a = b, true : false;
}
template <typename T>
bool chmin(T& a, const T& b) {
  return a > b ? a = b, true : false;
}
#include <bits/extc++.h>

struct MinCostFlow {
  const ll INF = 1e18;
  struct Edge {
    ll from, to, rev, cap, cost, flow;
  };
  ll n;
  vv<Edge> ed;
  vl seen;
  vl dist, pi;
  vec<Edge*> par;
  MinCostFlow(ll n) : n(n), ed(n), seen(n), dist(n), pi(n), par(n) {}
  void add_edge(ll from, ll to, ll cap, ll cost) {
    if (from == to) return;
    ed[from].push_back(Edge{from, to, sz(ed[to]), cap, cost, 0});
    ed[to].push_back(Edge{to, from, sz(ed[from]) - 1, 0, -cost, 0});
  }
  void path(ll s) {
    fill(all(seen), 0);
    fill(all(dist), INF);
    dist[s] = 0;
    ll di;
    using Pq = __gnu_pbds::priority_queue<pll>;
    Pq q;
    vec<Pq::point_iterator> its(n);
    q.push({0, s});
    while (!q.empty()) {
      s = q.top().second;
      q.pop();
      seen[s] = 1;
      di = dist[s] + pi[s];
      for (Edge& e : ed[s])
        if (!seen[e.to]) {
          ll val = di - pi[e.to] + e.cost;
          if (e.cap - e.flow > 0 && val < dist[e.to]) {
            dist[e.to] = val;
            par[e.to] = &e;
            if (its[e.to] == q.end()) its[e.to] = q.push({-dist[e.to], e.to});
            else q.modify(its[e.to], {-dist[e.to], e.to});
          }
        }
    }
    rep(i, n) pi[i] = min(pi[i] + dist[i], INF);
  }
  pll maxflow(ll s, ll t) {
    ll totflow = 0, totcost = 0;
    while (path(s), seen[t]) {
      ll fl = INF;
      for (Edge* x = par[t]; x; x = par[x->from])
        fl = min(fl, x->cap - x->flow);
      totflow += fl;
      for (Edge* x = par[t]; x; x = par[x->from]) {
        x->flow += fl;
        ed[x->to][x->rev].flow -= fl;
      }
    }
    rep(i, n) for (Edge& e : ed[i]) totcost += e.cost * e.flow;
    return {totflow, totcost / 2};
  }
  void setpi(ll s) {
    fill(all(pi), INF);
    pi[s] = 0;
    ll it = n, ch = 1;
    ll v;
    while (ch-- && it--)
      rep(i, n) if (pi[i] != INF) for (Edge& e : ed[i]) if (e.cap) if ((v = pi[i] + e.cost) < pi[e.to]) pi[e.to] = v, ch = 1;
    assert(it >= 0);
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  ll n;
  string s;
  cin >> n >> s;
  vl v(n);
  rep(i, n) cin >> v[i];

  vv<ll> nxt(4, vl(n, n));
  rrep(i, 0, n) {
    if(i != n-1) rep(j, 4) chmin(nxt[j][i], nxt[j][i+1]);
    if(i == 0) continue;
    rep(j, 4) if(s[i] == "yuki"[j]) nxt[j][i-1] = i;
  }

  MinCostFlow mcf(n + 2);

  mcf.add_edge(n, s[0] == 'y' ? 0 : nxt[0][0], 1e18, 0);

  rep(i, n) {
    rep(j, 4) if(s[i] == "yuki"[j] && nxt[j][i] < n) mcf.add_edge(i, nxt[j][i], 1e18, 0);
    rep(j, 3) if(s[i] == "yuki"[j] && nxt[j+1][i] < n) mcf.add_edge(i, nxt[j+1][i], 1, -v[i]);
    if(s[i] == 'i') mcf.add_edge(i, n+1, 1, -v[i]);
  }

  mcf.setpi(n);

  cout << -mcf.maxflow(n, n+1).second << endl;
}
0