競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 320D問題

ABC332D

解法

行と列の個数が\(5\)以下と少ないので全探索できる. 入れ替え全体は\(\,(5!)^{2}\,\)通り. 置換を与えたとき,互換の積で表したときの最小の個数は, 置換の転倒数と一致. これは愚直に実装でも,置換のサイズの2乗オーダーで求まる. Segtree を使えば,\(O(N log N)\)も可能.

使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"

ll inv(vll &v){
  ll n = v.size();
  ll ans = 0;
  rep(i,n) rep(j,i){
    if(v[i] < v[j]) ans++;
  }
  return ans;
}

int main() {
  ll h,w; cin >> h >> w;
  vvll a(h, vll(w)); cinvv(a);
  vvll b(h, vll(w)); cinvv(b);

  vll p(h), q(w);
  rep(i,h) p[i] = i;
  rep(i,w) q[i] = i;

  ll ans = INFL;
  do{
    do{
      vvll na(h, vll(w));
      rep(i,h) rep(j,w){
        na[i][j] = a[p[i]][q[j]];
      }

      if(na == b){
        ll x = 0;
        x += inv(p);
        x += inv(q);
        chmin(ans, x);
      }
     
    }while(next_permutation(all(p)));
  }while(next_permutation(all(q)));

  if(ans == INFL) ans = -1;
  cout << ans << endl;

  return 0;
}