結果
| 問題 | 
                            No.200 カードファイト!
                             | 
                    
| コンテスト | |
| ユーザー | 
                             | 
                    
| 提出日時 | 2017-05-22 16:13:27 | 
| 言語 | D  (dmd 2.109.1)  | 
                    
| 結果 | 
                             
                                AC
                                 
                             
                            
                         | 
                    
| 実行時間 | 4 ms / 2,000 ms | 
| コード長 | 2,984 bytes | 
| コンパイル時間 | 976 ms | 
| コンパイル使用メモリ | 134,540 KB | 
| 実行使用メモリ | 6,944 KB | 
| 最終ジャッジ日時 | 2024-06-12 19:20:13 | 
| 合計ジャッジ時間 | 1,745 ms | 
| 
                            ジャッジサーバーID (参考情報)  | 
                        judge5 / judge1 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 3 | 
| other | AC * 26 | 
ソースコード
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;
  }
}