Problem:
Score : 600 points

Problem Statement

There are 2N balls, N white and N black, arranged in a row. The integers from 1 through N are written on the white balls, one on each ball, and they are also written on the black balls, one on each ball.
The integer written on the i-th ball from the left (1 ≤ i ≤ 2N) is a_i, and the color of this ball is represented by a letter c_i.
c_i = W represents the ball is white; c_i = B represents the ball is black.

Takahashi the human wants to achieve the following objective:

For every pair of integers (i,j) such that 1 ≤ i < j ≤ N, the white ball with i written on it is to the left of the white ball with j written on it.

For every pair of integers (i,j) such that 1 ≤ i < j ≤ N, the black ball with i written on it is to the left of the black ball with j written on it.

In order to achieve this, he can perform the following operation:

Swap two adjacent balls.

Find the minimum number of operations required to achieve the objective.

Constraints

1 ≤ N ≤ 2000

1 ≤ a_i ≤ N

c_i = W or c_i = B.

If i ≠ j, (a_i,c_i) ≠ (a_j,c_j).

Input

Input is given from Standard Input in the following format:

N
c_1 a_1
c_2 a_2
:
c_{2N} a_{2N}

Output

Print the minimum number of operations required to achieve the objective.

Sample Input 1

3
B 1
W 2
B 3
W 1
W 3
B 2

Sample Output 1

4

The objective can be achieved in four operations, for example, as follows:

Swap the black 3 and white 1.

Swap the white 1 and white 2.

Swap the black 3 and white 3.

Swap the black 3 and black 2.

Sample Input 2

4
B 4
W 4
B 3
W 3
B 2
W 2
B 1
W 1

Sample Output 2

18

Sample Input 3

9
W 3
B 1
B 4
W 1
B 5
W 9
W 2
B 6
W 5
B 3
W 8
B 9
W 7
B 2
B 8
W 4
W 6
B 7

Sample Output 3

41

Solution in Rust (1.15.1) (judge verdict: Accepted)

fn main() {
    let n: usize = readln();
    let v: Vec<(String, usize)> = readlns(2 * n);
    let mut index_b: HashMap<usize, usize> = HashMap::new();
    let mut index_w: HashMap<usize, usize> = HashMap::new();

    let L = 63;
    let B = (v.len() + L - 1) / L;
    let mut bucket_b = vec![vec![0; n + 2]; B];
    let mut bucket_w = vec![vec![0; n + 2]; B];
    for (idx, &(ref c, x)) in v.iter().enumerate() {
        let b = idx / L;
        if c == "B" {
            bucket_b[b][x] += 1;
        } else {
            bucket_w[b][x] += 1;
        }
    }
    for i in 0..B {
        for j in (1..n + 1).rev() {
            bucket_b[i][j - 1] += bucket_b[i][j];
            bucket_w[i][j - 1] += bucket_w[i][j];
        }
    }

    for (idx, &(ref c, x)) in v.iter().enumerate() {
        if c == "B" {
            index_b.insert(x, idx);
        } else {
            index_w.insert(x, idx);
        }
    }

    let mut dp = vec![vec![1000000000000i64; n + 2]; n + 2];
    dp[1][1] = 0;

    for b in 1..n + 2 {
        for w in 1..n + 2 {
            if b <= n {
                let idx = index_b[&b];
                // count x >= b or x >= w in v[0, idx]
                let id = idx / L;
                let mut cost = 0;
                for i in 0..id {
                    cost += bucket_b[i][b];
                    cost += bucket_w[i][w];
                }
                let begin = id * L;
                for i in begin..idx {
                    if v[i].0 == "B" && v[i].1 >= b {
                        cost += 1;
                    }
                    if v[i].0 == "W" && v[i].1 >= w {
                        cost += 1;
                    }
                }
                dp[b + 1][w] = min(dp[b + 1][w], dp[b][w] + cost);
            }
            if w <= n {
                let idx = index_w[&w];
                // count x >= b or x > w in v[0, idx]
                let id = idx / L;
                let mut cost = 0;
                for i in 0..id {
                    cost += bucket_b[i][b];
                    cost += bucket_w[i][w];
                }
                let begin = id * L;
                for i in begin..idx {
                    if v[i].0 == "B" && v[i].1 >= b {
                        cost += 1;
                    }
                    if v[i].0 == "W" && v[i].1 >= w {
                        cost += 1;
                    }
                }
                dp[b][w + 1] = min(dp[b][w + 1], dp[b][w] + cost);
            }
        }
    }

    println!("{}", dp[n + 1][n + 1]);
}

#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::{HashMap, HashSet, VecDeque};

pub trait FromLn {
    fn fromln(s: &str) -> Self;
}
pub fn readln<T: FromLn>() -> T {
    let mut buf = String::new();
    let _ = ::std::io::stdin().read_line(&mut buf).unwrap();
    T::fromln(buf.trim())
}
pub fn readlns<T: FromLn>(n: usize) -> Vec<T> {
    let mut vs = vec![];
    for _ in 0..n {
        vs.push(readln());
    }
    vs
}
macro_rules! fromln_primitives {
    ($($t:ty),*) => { $(
        impl FromLn for $t {
            fn fromln(s: &str) -> $t {
                s.parse().unwrap()
            }
        }
    )* }
}
fromln_primitives!(String, bool, f32, f64, isize, i8, i16, i32, i64, usize, u8, u16, u32, u64);
impl<T> FromLn for Vec<T>
where
    T: FromLn,
{
    fn fromln(s: &str) -> Vec<T> {
        s.split_whitespace().map(T::fromln).collect()
    }
}
impl FromLn for Vec<char> {
    fn fromln(s: &str) -> Vec<char> {
        s.chars().collect()
    }
}
macro_rules! fromln_tuple {
    ($($t:ident),*) => {
        impl<$($t),*> FromLn for ($($t),*) where $($t: FromLn),* {
            fn fromln(s: &str) -> ($($t),*) {
                let mut it = s.split_whitespace();
                let t = ($($t::fromln(it.next().unwrap())),*);
                assert_eq!(it.next(), None);
                t
            }
        }
    }
}
fromln_tuple!(A, B);
fromln_tuple!(A, B, C);
fromln_tuple!(A, B, C, D);
fromln_tuple!(A, B, C, D, E);
fromln_tuple!(A, B, C, D, E, F);