解法

概要

結果の列を固定すれば転倒数を計算するだけ。 結果の列を前から構成していってその過程を白黒のボールの使った数 \((w, b)\) で割ってDP。 列中の確定した部分の数字についての転倒数の和を持つ。 これをそのまま書くと \(O(N^3)\) になる。 適当に前処理するなどすると \(O(N^2)\) に落ちる。

実装

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i))
using namespace std;
template <class T, class U> inline void chmin(T & a, U const & b) { a = min<T>(a, b); }
template <typename X, typename T> auto vectors(X x, T a) { return vector<T>(x, a); }
template <typename X, typename Y, typename Z, typename... Zs> auto vectors(X x, Y y, Z z, Zs... zs) { auto cont = vectors(y, z, zs...); return vector<decltype(cont)>(x, cont); }

int solve(int n, vector<char> const & c, vector<int> const & a) {
    auto delta_w = vectors(n + 1, n + 1, int());
    REP (w, n + 1) {
        REP (i, 2 * n) {
            if (c[i] == 'B') {
                delta_w[w][0] += 1;
                delta_w[w][a[i] + 1] -= 1;
            } else {
                if (a[i] == w) break;
                delta_w[w][0] += (a[i] >= w);
            }
        }
        REP (b, n) {
            delta_w[w][b + 1] += delta_w[w][b];
        }
    }

    auto delta_b = vectors(n + 1, n + 1, int());
    REP (b, n + 1) {
        REP (i, 2 * n) {
            if (c[i] == 'B') {
                if (a[i] == b) break;
                delta_b[0][b] += (a[i] >= b);
            } else {
                delta_b[0][b] += 1;
                delta_b[a[i] + 1][b] -= 1;
            }
        }
        REP (w, n) {
            delta_b[w + 1][b] += delta_b[w][b];
        }
    }

    auto dp = vectors(n + 1, n + 1, INT_MAX);
    dp[0][0] = 0;
    REP (w, n + 1) {
        REP (b, n + 1) {
            if (w - 1 >= 0) {
                chmin(dp[w][b], dp[w - 1][b] + delta_w[w - 1][b]);
            }
            if (b - 1 >= 0) {
                chmin(dp[w][b], dp[w][b - 1] + delta_b[w][b - 1]);
            }
        }
    }
    return dp[n][n];
}

int main() {
    int n; cin >> n;
    vector<char> c(2 * n);
    vector<int> a(2 * n);
    REP (i, 2 * n) {
        cin >> c[i] >> a[i];
        -- a[i];
    }
    cout << solve(n, c, a) << endl;
    return 0;
}