結果

問題 No.200 カードファイト!
ユーザー te-shte-sh
提出日時 2017-05-22 16:13:27
言語 D
(dmd 2.105.2)
結果
AC  
実行時間 5 ms / 2,000 ms
コード長 2,984 bytes
コンパイル時間 1,793 ms
コンパイル使用メモリ 120,248 KB
実行使用メモリ 4,380 KB
最終ジャッジ日時 2023-09-03 13:29:30
合計ジャッジ時間 3,260 ms
ジャッジサーバーID
(参考情報)
judge14 / judge13
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 3 ms
4,376 KB
testcase_01 AC 4 ms
4,380 KB
testcase_02 AC 2 ms
4,380 KB
testcase_03 AC 2 ms
4,380 KB
testcase_04 AC 1 ms
4,380 KB
testcase_05 AC 3 ms
4,380 KB
testcase_06 AC 4 ms
4,380 KB
testcase_07 AC 3 ms
4,376 KB
testcase_08 AC 3 ms
4,376 KB
testcase_09 AC 4 ms
4,376 KB
testcase_10 AC 2 ms
4,380 KB
testcase_11 AC 2 ms
4,376 KB
testcase_12 AC 2 ms
4,380 KB
testcase_13 AC 2 ms
4,380 KB
testcase_14 AC 2 ms
4,376 KB
testcase_15 AC 1 ms
4,380 KB
testcase_16 AC 1 ms
4,376 KB
testcase_17 AC 1 ms
4,380 KB
testcase_18 AC 1 ms
4,380 KB
testcase_19 AC 2 ms
4,376 KB
testcase_20 AC 3 ms
4,380 KB
testcase_21 AC 2 ms
4,376 KB
testcase_22 AC 2 ms
4,380 KB
testcase_23 AC 2 ms
4,376 KB
testcase_24 AC 2 ms
4,376 KB
testcase_25 AC 2 ms
4,380 KB
testcase_26 AC 2 ms
4,380 KB
testcase_27 AC 3 ms
4,380 KB
testcase_28 AC 5 ms
4,380 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import std.algorithm, std.conv, std.range, std.stdio, std.string;

void main()
{
  auto n = readln.chomp.to!size_t;
  auto al = readln.chomp.to!size_t;
  auto ai = readln.split.to!(int[]); ai.sort().reverse;
  auto bl = readln.chomp.to!size_t;
  auto bi = readln.split.to!(int[]); bi.sort();

  auto pai = new int[](n), pbi = new int[](n);
  foreach (i; 0..n) {
    pai[i] = ai[i % al];
    pbi[i] = bi[i % bl];
  }

  auto g = new Edge[][](n * 2 + 2);
  foreach (i; 0..n) {
    g[n*2] ~= Edge(n*2, i, 1, 0);
    g[i+n] ~= Edge(i+n, n*2+1, 1, 0);
  }

  foreach (i; 0..n) {
    auto aps = i / al * al, ape = min(n - 1, aps + al - 1);
    auto bps = aps / bl * bl, bpe = min(n - 1, ape / bl * bl + bl - 1);
    foreach (j; bps..bpe+1)
      g[i] ~= Edge(i, j+n, 1, pai[i] > pbi[j] ? 0 : 1);
  }

  auto r = graph.primalDual(g, n*2, n*2+1, n.to!int);
  writeln(n - r.cost);
}

alias Graph!(int, int, size_t) graph;
alias graph.Edge Edge;

template Graph(Wt, Ct, Node, Wt _inf = 10 ^^ 9, Node _sent = Node.max)
{
  import std.algorithm, std.container, std.typecons;

  const inf = _inf, sent = _sent;

  struct Edge { Node src, dst; Wt cap;  Ct cost; }
  struct EdgeR { Node src, dst; Wt cap, flow; Ct cost; Node rev; }
  alias Tuple!(Ct, "cost", Wt, "flow") Cf;

  Cf primalDual(Edge[][] g, Node s, Node t, Wt rest = inf)
  {
    auto n = g.length;
    auto adj = withRev(g, n);

    auto p = new Wt[](n);
    Wt flow;
    Ct cost;

    auto rcost(EdgeR e) { return e.cost + p[e.src] - p[e.dst]; }

    for (;;) {
      auto prev = new Node[](n); prev[] = sent; prev[s] = 0;
      auto dist = new Ct[](n); dist[] = inf; dist[s] = 0;

      struct Cv { Ct cost; Node v; }

      auto q = heapify!("a.cost > b.cost")(Array!Cv(Cv(0, s)));
      while (!q.empty) {
        auto a = q.front(); q.removeFront();
        if (a.v == t) break;
        if (dist[a.v] > a.cost) continue;
        foreach (e; adj[a.v]) {
          if (e.cap > e.flow && dist[e.dst] > a.cost + rcost(e)) {
            dist[e.dst] = dist[e.src] + rcost(e);
            prev[e.dst] = e.rev;
            q.insert(Cv(dist[e.dst], e.dst));
          }
        }
      }
      if (prev[t] == sent) break;

      foreach (u; 0..n)
        if (dist[u] < dist[t])
          p[u] += dist[u] - dist[t];

      Wt augment(Node u, Wt cur) {
        if (u == s) return cur;
        auto r = &adj[u][prev[u]], e = &adj[r.dst][r.rev];
        auto f = augment(e.src, min(e.cap - e.flow, cur));
        e.flow += f;
        r.flow -= f;
        return f;
      }

      auto f = augment(t, rest);
      if (f == 0) break;

      flow += f;
      cost += f * (p[t] - p[s]);
      rest -= f;
    }

    return Cf(cost, flow);
  }

  EdgeR[][] withRev(Edge[][] g, size_t n)
  {
    auto r = new EdgeR[][](n);

    foreach (gi; g)
      foreach (e; gi) {
        r[e.src] ~= EdgeR(e.src, e.dst, e.cap, 0, e.cost, r[e.dst].length);
        r[e.dst] ~= EdgeR(e.dst, e.src, 0, 0, -e.cost, r[e.src].length - 1);
      }

    return r;
  }
}
0