Problem:
たのしいたのしいたのしい家庭菜園(Growing Vegetables is Fun 3)
JOI 君は，長年にわたる家庭菜園の経験を生かして，自宅の庭で新たにジョイ草という植物を育てている．庭には東西方向に並んだ$N$ 個のプランターがあり，西側から順に1 から$N$ までの番号がついている．ジョイ草は全部で$N$ 株あり，それぞれのプランターに1 株ずつ植えてある．
春になって様子を見に行ったJOI 君は，ジョイ草が予想に反して色とりどりの葉を付けていることに気がついた．さらに，ジョイ草が思ったほど生育していないことに気がついた．JOI 君はこれらのことを不思議に思い，本で調べたところ，次のことがわかった：
ジョイ草には3 種類あり，それぞれ赤，緑，黄の葉を付ける．
葉の色が同じジョイ草を近くに置くと，その成長が阻害されてしまう．
そこで，JOI 君は，ジョイ草を並び替えて，葉の色が同じジョイ草が隣り合わないようにすることにした．このとき，JOI 君は隣り合う2 つのジョイ草を入れ替えることしかできない．つまり，1 回の操作でJOI 君はプランター$i$ ($1 \leq i \leq N - 1$) を任意に1 つ選び，プランター$i$ のジョイ草とプランター$i + 1$ のジョイ草を入れ替えることができる．JOI 君は，できるだけ少ない回数の操作で，葉の色が同じジョイ草が隣り合わないようにしたい．
ジョイ草の数と，それぞれのジョイ草の葉の色が与えられたとき，葉の色が同じジョイ草が隣り合わないように並び替えるために必要な操作回数の最小値を求めるプログラムを作成せよ．
入力
入力は以下の形式で標準入力から与えられる．
$N$
$S$
$S$ は長さ$N$ の文字列で，その$i$ 文字目($1 \leq i \leq N$) は，プランター$i$ に植えてあるジョイ草の葉の色が赤ならばR，緑ならばG，黄ならばY である．
出力
標準出力に，必要な操作回数の最小値を1 行で出力せよ．ただし，葉の色が同じジョイ草が隣り合わないように並び替えることが不可能ならば，代わりに-1 を出力せよ．
制約
$ 1 \leq N \leq 400$．
$S$ は長さ$N$ の文字列である．
$S$ の各文字はR，G，Y のいずれかである．
入出力例
入力例1
5
RRGYY
出力例1
2
この入力例では，例えば次のようにすると，葉の色が同じジョイ草が隣り合わないようにすることができる．
まず，プランター3 のジョイ草とプランター4 のジョイ草を入れ替える．
次に，プランター2 のジョイ草とプランター3 のジョイ草を入れ替える．
このようにすると，ジョイ草の並びはRYRGY のようになる．1 回以下の操作で葉の色が同じジョイ草が隣り合わないようにすることはできないので，2 を出力する．
入力例2
6
RRRRRG
出力例2
-1
この入力例では，どのように操作をしても，葉の色が同じジョイ草が隣り合わないようにすることはできない．
入力例3
20
YYGYYYGGGGRGYYGRGRYG
出力例3
8
情報オリンピック日本委員会作 『第18 回日本情報オリンピック(JOI 2018/2019) 本選』

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()

#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define btpc __builtin_popcountll
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const double Pi=3.141592653589793;
void file(const string FILE){
    if (fopen((FILE + ".INP").c_str(),"r")){
        freopen((FILE + ".INP").c_str(), "r", stdin);
        freopen((FILE + ".OUT").c_str(), "w", stdout);
    }
}
const int N = 401;
const int inf = 1e9;
int dp[N][201][201][3];
int pos[3][N];
int cnt[N][3];
void solve()
{
	int n; cin >> n;
	string s; cin >> s;
	s = ' ' + s;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < 3; j++) cnt[i][j] = cnt[i - 1][j];
		if(s[i] == 'R') ++cnt[i][0], pos[0][cnt[i][0] - 1] = i;
		if(s[i] == 'G') ++cnt[i][1], pos[1][cnt[i][1] - 1] = i;
		if(s[i] == 'Y') ++cnt[i][2], pos[2][cnt[i][2] - 1] = i;
	}
	dp[0][0][0][0] = 0;
	dp[0][0][0][1] = 0;
	dp[0][0][0][2] = 0;
	if (cnt[n][0] > (n + 1) /2 || cnt[n][1] > (n + 1) / 2 || cnt[n][2] > (n + 1) / 2) {
		cout << -1 << endl;
		return;
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= min(cnt[n][0], i); j++) {
			for (int k = 0; k <= min(cnt[n][1], i - j); k++) {
				int z = i - j - k;
				for (int c = 0; c < 3; c++) dp[i][j][k][c] = inf;
				if (j > cnt[n][0] || k > cnt[n][1] || z > cnt[n][2] || z < 0) continue;
				if (j > 0) {
					dp[i][j][k][0] = min(dp[i - 1][j - 1][k][1], dp[i - 1][j - 1][k][2]) + max(0, k - cnt[pos[0][j - 1]][1]) + max(0, z - cnt[pos[0][j - 1]][2]);
				}
				if (k > 0) {
					dp[i][j][k][1] = min(dp[i - 1][j][k - 1][0], dp[i - 1][j][k - 1][2]) + max(0, j - cnt[pos[1][k - 1]][0]) + max(0, z - cnt[pos[1][k - 1]][2]);
				}
				if (z > 0) {
					dp[i][j][k][2] = min(dp[i - 1][j][k][0], dp[i - 1][j][k][1]) + max(0, j - cnt[pos[2][z - 1]][0]) + max(0, k - cnt[pos[2][z - 1]][1]);
				}
			}
		}
	}
	int ans = inf;
	for (int c = 0; c < 3; c++) ans = min(ans, dp[n][cnt[n][0]][cnt[n][1]][c]);
	if (ans >= inf) cout << -1 << endl;
	else cout << ans << endl;
	// CODE HERE
}

int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int t = 1;
//	cin >> t;
	while(t--){
		solve();
	}
}
accuracy: 1
time_ms: 20
memory_kb: 191352
final_rank: 15

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
using namespace std;

#define INF (1 << 30)

int N;
int col[440];
vector<vector<vector<vector<int>>>> dp;
int pos[4][440];
int csum[4];
int bit[440];

int sum(int i) {
    int s = 0;
    while (i > 0) {
        s += bit[i];
        i -= i & -i;
    }
    return s;
}

void add(int i, int x) {
    while (i <= N) {
        bit[i] += x;
        i += i & -i;
    }
}

int dfs(int c, int x, int y, int z) {
    if (x + y + z == N) return 0;
    if (dp[c][x][y][z] != -1) return dp[c][x][y][z];
    int ret = INF;
    if (x < csum[1] && c != 1) {
        add(pos[1][x + 1], 1);
        ret = min(ret, dfs(1, x + 1, y, z) + pos[1][x + 1] - sum(pos[1][x + 1]));
        add(pos[1][x + 1], -1);
    }
    if (y < csum[2] && c != 2) {
        add(pos[2][y + 1], 1);
        ret = min(ret, dfs(2, x, y + 1, z) + pos[2][y + 1] - sum(pos[2][y + 1]));
        add(pos[2][y + 1], -1);
    }
    if (z < csum[3] && c != 3) {
        add(pos[3][z + 1], 1);
        ret = min(ret, dfs(3, x, y, z + 1) + pos[3][z + 1] - sum(pos[3][z + 1]));
        add(pos[3][z + 1], -1);
    }
    return dp[c][x][y][z] = ret;
}

int main() {
    cin >> N;
    int cnt1 = 0, cnt2 = 0, cnt3 = 0;
    for (int i = 1; i <= N; i++) {
        char a;
        cin >> a;
        if (a == 'R') {
            col[i] = 1;
            cnt1++;
            pos[1][cnt1] = i;
            csum[1]++;
        } else if (a == 'G') {
            col[i] = 2;
            cnt2++;
            pos[2][cnt2] = i;
            csum[2]++;
        } else {
            col[i] = 3;
            cnt3++;
            pos[3][cnt3] = i;
            csum[3]++;
        }
    }

    dp.resize(4, vector<vector<vector<int>>>(csum[1] + 10, vector<vector<int>>(csum[2] + 10, vector<int>(csum[3] + 10, -1))));

    int ans = dfs(0, 0, 0, 0);
    if (ans >= INF) ans = -1;
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 65008
final_rank: 11

code_snippet: #include <string>
#include <vector>
#include <iostream>
#include <cmath>
#include <climits>
static std::vector<int> redPosition;
static std::vector<int> greenPosition;
static std::vector<int> yellowPosition;
static std::vector<int> countLeftRed;
static std::vector<int> countLeftGreen;
static std::vector<int> countLeftYellow;
static int redSize;
static int greenSize;
static int yellowSize;
static int wholeSize;
struct Key {
	int position, red, green, yellow, last;
	bool operator<(const Key& other) const {
		if (position == other.position) {
			if (red == other.red) {
				if (green == other.green) {
					if (yellow == other.yellow) {
						return last < other.last;
					}
					else {
						return yellow < other.yellow;
					}
				}
				else {
					return green < other.green;
				}
			}
			else {
				return red < other.red;
			}
		}
		else {
			return position < other.position;
		}
	}
	bool operator==(const Key& other) const {
		return position == other.position && red == other.red && green == other.green && yellow == other.yellow && last == other.last;
	}
};
static std::vector < std::vector<std::vector<std::vector<int>>>> memo;
int solve(const int position, const int red, const int green, const int yellow, const int last) {
	if (position == wholeSize && red == redSize && green == greenSize && yellow == yellowSize) return 0;
	if (red > redSize || green > greenSize || yellow > yellowSize || wholeSize - position + 1 < (redSize - red) * 2 || wholeSize - position + 1 < (greenSize - green) * 2 || wholeSize - position + 1 < (yellowSize - yellow) * 2) return INT_MAX >> 1;
	if (last < 3 && memo[red][green][yellow][last] >= 0) return memo[red][green][yellow][last];
	int result = INT_MAX;
	switch (last) {
	case 0:
		if (green != greenSize) result = std::min(result, solve(position + 1, red, green + 1, yellow, 1) + std::max(countLeftRed[greenPosition[green]] - red, 0) + std::max(countLeftYellow[greenPosition[green]] - yellow, 0));
		if (yellow != yellowSize) result = std::min(result, solve(position + 1, red, green, yellow + 1, 2) + std::max(countLeftRed[yellowPosition[yellow]] - red, 0) + std::max(countLeftGreen[yellowPosition[yellow]] - green, 0));
		break;
	case 1:
		if (red != redSize) result = solve(position + 1, red + 1, green, yellow, 0) + std::max(countLeftGreen[redPosition[red]] - green, 0) + std::max(countLeftYellow[redPosition[red]] - yellow, 0);
		if (yellow != yellowSize) result = std::min(result, solve(position + 1, red, green, yellow + 1, 2) + std::max(countLeftRed[yellowPosition[yellow]] - red, 0) + std::max(countLeftGreen[yellowPosition[yellow]] - green, 0));
		break;
	case 2:
		if (red != redSize) result = solve(position + 1, red + 1, green, yellow, 0) + std::max(countLeftGreen[redPosition[red]] - green, 0) + std::max(countLeftYellow[redPosition[red]] - yellow, 0);
		if (green != greenSize) result = std::min(result, solve(position + 1, red, green + 1, yellow, 1) + std::max(countLeftRed[greenPosition[green]] - red, 0) + std::max(countLeftYellow[greenPosition[green]] - yellow, 0));
		break;
	default:
		if (red != redSize) result = solve(position + 1, red + 1, green, yellow, 0) + std::max(countLeftGreen[redPosition[red]] - green, 0) + std::max(countLeftYellow[redPosition[red]] - yellow, 0);
		if (green != greenSize) result = std::min(result, solve(position + 1, red, green + 1, yellow, 1) + std::max(countLeftRed[greenPosition[green]] - red, 0) + std::max(countLeftYellow[greenPosition[green]] - yellow, 0));
		if (yellow != yellowSize) result = std::min(result, solve(position + 1, red, green, yellow + 1, 2) + std::max(countLeftRed[yellowPosition[yellow]] - red, 0) + std::max(countLeftGreen[yellowPosition[yellow]] - green, 0));
	}
	if (last == 3) return result;
	return memo[red][green][yellow][last] = result;
}
int solve(const std::string& state) {
	countLeftRed = countLeftGreen = countLeftYellow = std::vector<int>(state.size(), 0);
	for (auto i = 0; i < state.size(); ++i) {
		switch (state[i]) {
		case 'R': redPosition.push_back(i); countLeftRed[i] = 1; break;
		case 'G': greenPosition.push_back(i); countLeftGreen[i] = 1; break;
		case 'Y': yellowPosition.push_back(i); countLeftYellow[i] = 1;  break;
		default: break;
		}
		if (i != 0) {
			countLeftRed[i] += countLeftRed[i - 1];
			countLeftGreen[i] += countLeftGreen[i - 1];
			countLeftYellow[i] += countLeftYellow[i - 1];
		}
	}
	redSize = redPosition.size();
	greenSize = greenPosition.size();
	yellowSize = yellowPosition.size();
	wholeSize = state.size();
	if (redSize * 2 > wholeSize + 1 || greenSize * 2 > wholeSize + 1 || yellowSize * 2 > wholeSize + 1) return -1;
	memo = std::vector<std::vector<std::vector<std::vector<int>>>>(redSize + 1, std::vector<std::vector<std::vector<int>>>(greenSize + 1, std::vector<std::vector<int>>(yellowSize + 1, std::vector<int>(3, -1))));
	return solve(0, 0, 0, 0, 3);
}
int main() {
	int n; std::cin >> n; std::string str; std::cin >> str;
	std::cout << solve(str) << std::endl;
}
accuracy: 1
time_ms: 150
memory_kb: 137048
final_rank: 17

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cassert>
#include <chrono>
#include <random>
#include <set>
#include <utility>
#include <array>
#include <bitset>
#include <unordered_set>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<int> s(n);
    vector<vector<int>> v(3);
    vector<vector<int>> sum(3, vector<int>(n+1));
    for (int i = 0; i < n; ++i) {
        char c; cin >> c;
        if (c == 'R') s[i] = 0;
        else if (c == 'G') s[i] = 1;
        else s[i] = 2;

        sum[s[i]][i+1] += 1;
        v[s[i]].push_back(i);
        for (int j = 0; j < 3; ++j) {
            sum[j][i+1] += sum[j][i];
        }
    }
    int r = (int)v[0].size();
    int g = (int)v[1].size();
    int y = (int)v[2].size();

    vector<vector<int>> dp0(r+1, vector<int>(g+1, 1e9));
    vector<vector<int>> dp1(r+1, vector<int>(g+1, 1e9));
    vector<vector<int>> dp2(r+1, vector<int>(g+1, 1e9));
    dp0[0][0] = dp1[0][0] = dp2[0][0] = 0;
    for (int i = 0; i < n; ++i) {
        vector<vector<int>> ndp0(r+1, vector<int>(g+1, 1e9));
        vector<vector<int>> ndp1(r+1, vector<int>(g+1, 1e9));
        vector<vector<int>> ndp2(r+1, vector<int>(g+1, 1e9));

        for (int j = 0; j <= r and j <= i; ++j) {
            for (int k = 0; k <= g and j+k <= i; ++k) {
                int l = i-j-k;

                if (dp0[j][k] != 1e9) {
                    if (k+1 <= g) {
                        int pos = v[1][k];
                        int cost = max(0, sum[0][pos]-j) + max(0, sum[1][pos]-k) + max(0, sum[2][pos]-l);
                        ndp1[j][k+1] = min(ndp1[j][k+1], dp0[j][k]+cost);
                    }
                    if (l+1 <= y) {
                        int pos = v[2][l];
                        int cost = max(0, sum[0][pos]-j) + max(0, sum[1][pos]-k) + max(0, sum[2][pos]-l);
                        ndp2[j][k] = min(ndp2[j][k], dp0[j][k]+cost);
                    }
                }
                if (dp1[j][k] != 1e9) {
                    if (j+1 <= r) {
                        int pos = v[0][j];
                        int cost = max(0, sum[0][pos]-j) + max(0, sum[1][pos]-k) + max(0, sum[2][pos]-l);
                        ndp0[j+1][k] = min(ndp0[j+1][k], dp1[j][k]+cost);
                    }
                    if (l+1 <= y) {
                        int pos = v[2][l];
                        int cost = max(0, sum[0][pos]-j) + max(0, sum[1][pos]-k) + max(0, sum[2][pos]-l);
                        ndp2[j][k] = min(ndp2[j][k], dp1[j][k]+cost);
                    }
                }
                if (dp2[j][k] != 1e9) {
                    if (j+1 <= r) {
                        int pos = v[0][j];
                        int cost = max(0, sum[0][pos]-j) + max(0, sum[1][pos]-k) + max(0, sum[2][pos]-l);
                        ndp0[j+1][k] = min(ndp0[j+1][k], dp2[j][k]+cost);
                    }
                    if (k+1 <= g) {
                        int pos = v[1][k];
                        int cost = max(0, sum[0][pos]-j) + max(0, sum[1][pos]-k) + max(0, sum[2][pos]-l);
                        ndp1[j][k+1] = min(ndp1[j][k+1], dp2[j][k]+cost);
                    }
                }
            }
        }

        swap(dp0, ndp0);
        swap(dp1, ndp1);
        swap(dp2, ndp2);
    }
    int res = min({dp0[r][g], dp1[r][g], dp2[r][g]});
    if (res == 1e9) res = -1;
    cout << res << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 4336
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = int;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
#define all(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
template<class T>
bool chmax(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p < q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}
template<class T>
bool chmin(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p > q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    int N;
    string S;
    cin >> N >> S;
    vector<vector<int>> A(3, vector<int>(N + 1, 0));
    vector<vector<int>> C(3);
    rep(i, N) {
        if (S[i] == 'R') {
            C[0].push_back(i);
            A[0][i + 1]++;
        }
        else if (S[i] == 'G') {
            C[1].push_back(i);
            A[1][i + 1]++;
        }
        else {
            C[2].push_back(i);
            A[2][i + 1]++;
        }
        rep(k, 3)A[k][i + 1] += A[k][i];
    }

    vll Z(3);
    rep(i, 3) {
        Z[i] = A[i][N];
        if (Z[i] * 2 > N + 1) {
            cout << -1 << endl;
            return 0;
        }
    }
    vvvll DP(Z[0] + 1, vvll(Z[1] + 1, vll(3, 1e9)));
    vvvll NDP(Z[0] + 1, vvll(Z[1] + 1, vll(3, 1e9)));
    DP[0][0][0] = DP[0][0][1] = DP[0][0][2] = 0;
    rep(i, N) {
        NDP.assign(Z[0] + 1, vvll(Z[1] + 1, vll(3, 1e9)));
        rep(j, min(Z[0] + 1, i + 1)) {
            rep(k, min(Z[1] + 1, i + 1)) {
                int m = i - j - k;
                if (m > Z[2])continue;
                if (m < 0)break;
                //cout << i << " " << j << " " << k << " " << m << endl;
                if (m != Z[2]) {
                    int res = min(DP[j][k][0], DP[j][k][1]);
                    int id = C[2][m];
                    int cost = max(A[0][id + 1] - j, 0) + max(A[1][id + 1] - k, 0);

                    if (res + cost < NDP[j][k][2])NDP[j][k][2] = res + cost;
                }

                if (k != Z[1]) {
                    int res = min(DP[j][k][0], DP[j][k][2]);
                    int id = C[1][k];
                    int cost = max(A[0][id + 1] - j, 0) + max(A[2][id + 1] - m, 0);
                    if (res + cost < NDP[j][k + 1][1])NDP[j][k + 1][1] = res + cost;
                }

                if (j != Z[0]) {
                    int res = min(DP[j][k][1], DP[j][k][2]);
                    int id = C[0][j];
                    int cost = max(A[1][id + 1] - k, 0) + max(A[2][id + 1] - m, 0);
                    if (res + cost < NDP[j + 1][k][0])NDP[j + 1][k][0] = res + cost;
                }

            }
        }
        swap(DP, NDP);
    }
    int an = 1e9;
    rep(k, 3)an = min(an, DP[Z[0]][Z[1]][k]);
    cout << an << endl;

}
accuracy: 1
time_ms: 80
memory_kb: 7840
final_rank: 4

code_snippet: #include <bits/stdc++.h>
// #include <atcoder/all>

#define rep(i, x) for (int i = 0; i < x; i++)
#define rep2(i, x) for (int i = 1; i <= x; i++)
#define rep3(i, x, y) for (int i = x; i < y; i++)
#define REP(i, x) for (int i = x - 1; i >= 0; i--)
#define REP2(i, x) for (int i = x; i >= 1; i--)
#define mpa make_pair
#define mpt make_tuple
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define puts(x) cout << (x) << "\n"
using ll = long long;
using ld = long double;
using namespace std;
// using namespace atcoder;

constexpr ll INF = 1000000000000000000;
constexpr int intINF = 1000000000;
constexpr ll mod = 1000000007;
constexpr ll MOD = 998244353;
const ld pi = acos(-1);
// const ld EPS = 1e-9;
typedef string::const_iterator State;
class ParseError
{
};

template <typename T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}
template <typename T>
bool chmin(T &a, const T &b)
{
    if (a > b)
    {
        a = b; // aをbで更新
        return true;
    }
    return false;
}

bool isprime(ll p)
{
    if (p == 1)
        return false;
    for (ll i = 2; i * i <= p; i++)
    {
        if (p % i == 0)
            return false;
    }
    return true;
}
// エラトステネスの篩
vector<bool> isprime_format(ll n)
{
    vector<bool> P(n + 1, 1);
    P[0] = P[1] = 1;
    for (ll i = 2; i * i <= n; i++)
    {
        if (!P[i])
            continue;
        for (int j = i + i; j <= n; j += i)
            P[j] = false;
    }
    return P;
}
vector<ll> prime_format(ll n)
{
    vector<bool> P = isprime_format(n);
    vector<ll> ans;
    for (int i = 2; i <= n; i++)
    {
        if (P[i])
            ans.push_back(i);
    }
    return ans;
}
ll extGCD(ll a, ll b, ll &x, ll &y)
{
    // ax + by = cが整数解をもつための必要十分条件は c が gcd(a,b) で割り切れること。
    //  返り値: a と b の最大公約数
    //  ax + by = gcd(a, b) を満たす (x, y) が格納される
    // main関数内に extGCD(a, b, x, y); でx, yに解が格納
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    ll d = extGCD(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
ll keta(ll n)
{
    ll res = 0;
    while (n >= 1)
    {
        // res++;
        res += n % 10;

        n /= 10;
    }
    return res;
}
ll modpow(ll x, ll y, ll m)
{
    ll res = 1;
    while (y)
    {
        if (y % 2)
        {
            res *= x;
            res %= m;
        }
        x = x * x % m;
        y /= 2;
    }
    return res;
}

unsigned int xorshift()
{
    // xorshift　from 「ビット演算 (bit 演算) の使い方を総特集！ 」
    // 1~6まで出したいときは
    // xorshift() % 6 + 1
    static unsigned int tx = 123456789, ty = 362436069, tz = 521288629, tw = 88675123;
    unsigned int tt = (tx ^ (tx << 11));
    tx = ty;
    ty = tz;
    tz = tw;
    return (tw = (tw ^ (tw >> 19)) ^ (tt ^ (tt >> 8)));
}
uint64_t seed = 123456789;
uint64_t xorshift64()
{
    seed ^= seed << 13;
    seed ^= seed >> 17;
    seed ^= seed << 7;
    return seed;
}
int rand_int(int l, int r)
{
    return l + int(xorshift64() % (r - l));
}
double randouble()
{
    return double(xorshift64()) / double(uint64_t(-1));
}

typedef pair<ll, ll> P;
typedef pair<ll, P> pp;
// 左上右下
ll dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
ll ndx[4] = {1, -1, -1, 1}, ndy[4] = {1, 1, -1, -1};
char ds[4] = {'l', 'u', 'r', 'd'};
char dl[4] = {'L', 'U', 'R', 'D'};

vector<ll> spf;
void smallest_prime_factors(ll n)
{
    spf.resize(n + 1);
    spf[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        if (!spf[i])
        {
            for (int j = i; j < n; j += i)
            {
                spf[j] = i;
            }
        }
    }
}
std::map<int, int> high_speed_prime_factor(int n)
{
    std::map<int, int> res;
    while (n != 1)
    {
        res[spf[n]]++;
        n /= spf[n];
    }
    return res;
}

////////////////////////////////struct

struct Comb
{
    // https://atcoder.jp/contests/abc156/submissions/33741990

    ll nCrMAX;
    ll m;
    vector<ll> fac, finv, inv; // n!、1/n!、1/n

    Comb(ll kMOD, ll kMAX = 612345)
    {
        nCrMAX = kMAX;
        m = kMOD;
        fac.resize(nCrMAX);
        finv.resize(nCrMAX);
        inv.resize(nCrMAX);

        fac[0] = fac[1] = 1;
        finv[0] = finv[1] = 1;
        inv[1] = 1;
        for (int i = 2; i < nCrMAX; i++)
        {
            fac[i] = fac[i - 1] * i % m;
            inv[i] = m - inv[m % i] * (m / i) % m;
            finv[i] = finv[i - 1] * inv[i] % m;
        }
    }

    ll nCr(ll n, ll k)
    {
        if (k < nCrMAX)
        {
            ll res = 1;
            for (int i = n - k + 1; i <= n; i++)
            {
                res *= i;
                res %= m;
            }
            res = res * finv[k] % m;
            return res;
        }
        else
        {
            if (n < k)
                return 0;
            if (n < 0 || k < 0)
                return 0;
            return fac[n] * (finv[k] * finv[n - k] % m) % m;
        }
    }

    ll nCr1(ll n, ll k)
    {
        if (n < k)
            return 0;
        if (n < 0 || k < 0)
            return 0;
        return fac[n] * (finv[k] * finv[n - k] % m) % m;
    }

    //(nが大きくて)kが小さい時
    // nCrMAXはk+2まででOK
    ll nCr2(ll n, ll k)
    {
        ll res = 1;
        for (int i = n - k + 1; i <= n; i++)
        {
            res *= i;
            res %= m;
        }
        res = res * finv[k] % m;
        return res;
    }
};

struct status
{
    ll v;
    ll p;

    // bool operator<(const status& rhs) const { return c < rhs.c; };
    // bool operator>(const status& rhs) const { return c > rhs.c; };
    bool operator<(const status &rhs) const { return v < rhs.v; };
    bool operator>(const status &rhs) const { return v > rhs.v; };
};
void yes(bool a) { cout << (a ? "yes" : "no") << endl; }
void YES(bool a) { cout << (a ? "YES" : "NO") << endl; }
void Yes(bool a) { cout << (a ? "Yes" : "No") << endl; }
void Possible(bool a) { cout << (a ? "Possible" : "Impossible") << endl; }
// struct edge {
//	ll to; ll cost;
// };

struct Point
{
    ld x, y;
    Point operator+(const Point &p) const noexcept { return {x + p.x, y + p.y}; }
    Point operator-(const Point &p) const noexcept { return {x - p.x, y - p.y}; }
    Point operator*(const ld k) const noexcept { return {x * k, y * k}; }
    Point operator/(const ld k) const noexcept { return {x / k, y / k}; }
    Point &operator+=(const Point &p) noexcept
    {
        x += p.x;
        y += p.y;
        return *this;
    }
    Point &operator-=(const Point &p) noexcept
    {
        x -= p.x;
        y -= p.y;
        return *this;
    }
    bool operator<(const Point &p) const noexcept { return (x != p.x ? x < p.x : y < p.y); }

    ld abs() const noexcept { return sqrt(x * x + y * y); }
    ld norm() const noexcept { return x * x + y * y; }
};

// using mint = modint998244353;

struct edge
{
    ll to, cost;
};

ll dp[2][405][405][3];
// dp[i][r][g][l] : i番目までで Rがr個で Gがg個で 最後がlの時の 最小値

int main()
{
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    // cout << fixed << setprecision(15);
    // priority_queue<ll, vector<ll>, greater<ll>> que;
    // priority_queue<P, vector<P>, greater<P>> que;
    // priority_queue<status, vector<status>, greater<status>> que;

    map<char, ll> col;
    col['R'] = 0;
    col['G'] = 1;
    col['Y'] = 2;

    rep(i, 2)
    {
        rep(j, 405)
        {
            rep(k, 405)
            {
                rep(l, 3)
                {
                    dp[i][j][k][l] = INF;
                }
            }
        }
    }

    ll n;
    string s;
    cin >> n >> s;

    vector<vector<ll>> cnt(n, vector<ll>(3));   // cnt[i][j] : i番目までにcolor:jの花が何個か
    vector<vector<ll>> Where(n + 1, vector<ll>(3)); // Where[i][j] : i番目のcolor:jの花がどこにあるか
    int r = 0, g = 0, y = 0;
    rep(i, n)
    {
        if (s[i] == 'R')
        {
            r++;
            cnt[i][col[s[i]]]++;
            Where[r][0] = i;
        }
        if (s[i] == 'G')
        {
            g++;
            cnt[i][col[s[i]]]++;
            Where[g][1] = i;
        }
        if (s[i] == 'Y')
        {
            y++;
            cnt[i][col[s[i]]]++;
            Where[y][2] = i;
        }
        rep(l, 3)
        {
            if (i != 0) cnt[i][l] += cnt[i - 1][l];
        }
    }

    dp[0][0][0][0] = 0;
    dp[0][0][0][1] = 0;
    dp[0][0][0][2] = 0;
    ll ans = INF;
    rep2(i, n)
    {
        for (int a = 0; a <= i; a++)
        {
            for (int b = 0; a + b <= i; b++)
            {
                rep(l, 3) { dp[i % 2][a][b][l] = INF; }
                
                int c = i - a - b;
                if (a > r || b > g || c > y)
                {
                    continue;
                }
                if (a != 0)
                {
                    dp[i % 2][a][b][0] = min(dp[(i - 1) % 2][a - 1][b][1], dp[(i - 1) % 2][a - 1][b][2]) + max(0LL, b - cnt[Where[a][0]][1]) + max(0LL, c - cnt[Where[a][0]][2]);
                }
                if (b != 0)
                {
                    dp[i % 2][a][b][1] = min(dp[(i - 1) % 2][a][b - 1][0], dp[(i - 1) % 2][a][b - 1][2]) + max(0LL, a - cnt[Where[b][1]][0]) + max(0LL, c - cnt[Where[b][1]][2]);
                }
                if (c != 0)
                {
                    dp[i % 2][a][b][2] = min(dp[(i - 1) % 2][a][b][0], dp[(i - 1) % 2][a][b][1]) + max(0LL, a - cnt[Where[c][2]][0]) + max(0LL, b - cnt[Where[c][2]][1]);
                }
                if (i == n)
                {
                    rep(l, 3) { chmin(ans, dp[i % 2][a][b][l]); }
                }
            }
        }
    }
    cout << (ans == INF ? -1 : ans) << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 11200
final_rank: 2

code_snippet: #line 1 "solve/main.cpp"
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

/* template start */

#line 2 "lib/utility/type_alias.hpp"

#line 4 "lib/utility/type_alias.hpp"

using u64 = std::uint64_t;
using u32 = std::uint32_t;
using u16 = std::uint16_t;
using u8 = std::uint8_t;

using i64 = std::int64_t;
using i32 = std::int32_t;
using i16 = std::int16_t;
using i8 = std::int8_t;

using usize = std::size_t;
using isize = std::ptrdiff_t;

constexpr i64 operator"" _i64(unsigned long long num) { return i64(num); }

constexpr u64 operator"" _u64(unsigned long long num) { return u64(num); }
#line 33 "solve/main.cpp"

#define rep(i, a, b) for (i64 i = (a); (i) < (b); (i)++)
#define all(i) i.begin(), i.end()

#ifdef LOCAL
#define debug(...)                                                    \
  std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
      debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() { std::cerr << std::endl; }

template <typename Head, typename... Tail>
void debug_out(Head h, Tail... t) {
  std::cerr << " " << h;
  if (sizeof...(t) > 0) std::cerr << " :";
  debug_out(t...);
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, std::pair<T1, T2> pa) {
  return os << pa.first << " " << pa.second;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> vec) {
  for (std::size_t i = 0; i < vec.size(); i++)
    os << vec[i] << (i + 1 == vec.size() ? "" : " ");
  return os;
}

template <typename T1, typename T2>
inline bool chmax(T1& a, T2 b) {
  return a < b && (a = b, true);
}

template <typename T1, typename T2>
inline bool chmin(T1& a, T2 b) {
  return a > b && (a = b, true);
}

template <typename Num, typename Func = std::multiplies<Num>>
constexpr Num mypow(Num a, u64 b, Num id = 1, Func mul = Func()) {
  if (b == 0) return id;
  Num x = id;
  while (b > 0) {
    if (b & 1) x = mul(x, a);
    a = mul(a, a);
    b >>= 1;
  }
  return x;
}

/* template end */

enum Color {
  R,
  G,
  Y,
};

constexpr int INF = 5*1e8;

int dp[210][210][210][3];

int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);

  i64 n;
  std::cin >> n;

  std::string s;
  std::cin >> s;

  i64 r_cnt = 0, g_cnt = 0, y_cnt = 0;
  std::vector<i64> r_nth(1), g_nth(1), y_nth(1);

  rep(i, 0, n) {
    if (s[i] == 'R') {
      r_cnt++;
      r_nth.emplace_back(i);
    }
    if (s[i] == 'G') {
      g_cnt++;
      g_nth.emplace_back(i);
    }
    if (s[i] == 'Y') {
      y_cnt++;
      y_nth.emplace_back(i);
    }
  }

  if(r_cnt > (n+1)/2 || g_cnt > (n+1)/2 || y_cnt > (n+1)/2){
    std::cout<<-1<<"\n";
    return 0;
  }

  std::vector<i64> r_sum(n + 1, 0), g_sum(n + 1, 0), y_sum(n + 1, 0);
  rep(i, 0, n) {
    r_sum[i + 1] = r_sum[i];
    g_sum[i + 1] = g_sum[i];
    y_sum[i + 1] = y_sum[i];
    if (s[i] == 'R') {
      r_sum[i + 1] = r_sum[i] + 1;
    }
    if (s[i] == 'G') {
      g_sum[i + 1] = g_sum[i] + 1;
    }
    if (s[i] == 'Y') {
      y_sum[i + 1] = y_sum[i] + 1;
    }
  }

  rep(i, 0, 3) {
    dp[1][0][0][i] = INF;
    dp[0][1][0][i] = INF;
    dp[0][0][1][i] = INF;
  }

  if (r_cnt > 0) dp[1][0][0][R] = g_sum[r_nth[1]] + y_sum[r_nth[1]];
  if (g_cnt > 0) dp[0][1][0][G] = r_sum[g_nth[1]] + y_sum[g_nth[1]];
  if (y_cnt > 0) dp[0][0][1][Y] = r_sum[y_nth[1]] + g_sum[y_nth[1]];

  rep(sum, 2, n + 1) {
    rep(r, 0, r_cnt + 1) {
      if (r > sum) break;

      rep(g, 0, g_cnt + 1) {
        if (r + g > sum) break;

        i64 y = sum - r - g;

        if (y > y_cnt) continue;

        rep(i, 0, 3) dp[r][g][y][i] = INF;

        if (r > 0) {
          dp[r][g][y][R] = std::min(dp[r - 1][g][y][G], dp[r - 1][g][y][Y]);
          dp[r][g][y][R] += std::max(g_sum[r_nth[r]] - g, 0_i64);
          dp[r][g][y][R] += std::max(y_sum[r_nth[r]] - y, 0_i64);
        }

        if (g > 0) {
          dp[r][g][y][G] = std::min(dp[r][g - 1][y][R], dp[r][g - 1][y][Y]);
          dp[r][g][y][G] += std::max(r_sum[g_nth[g]] - r, 0_i64);
          dp[r][g][y][G] += std::max(y_sum[g_nth[g]] - y, 0_i64);
        }

        if (y > 0) {
          dp[r][g][y][Y] = std::min(dp[r][g][y - 1][R], dp[r][g][y - 1][G]);
          dp[r][g][y][Y] += std::max(r_sum[y_nth[y]] - r, 0_i64);
          dp[r][g][y][Y] += std::max(g_sum[y_nth[y]] - g, 0_i64);
        }

        debug(r, g, y, dp[r][g][y][R]);
        debug(r, g, y, dp[r][g][y][G]);
        debug(r, g, y, dp[r][g][y][Y]);
      }
    }
  }

  i64 ans = INF;
  rep(i, 0, 3) chmin(ans, dp[r_cnt][g_cnt][y_cnt][i]);

  if (ans == INF)
    std::cout << -1 << "\n";
  else
    std::cout << ans << "\n";

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 107840
final_rank: 8

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfenv>
#include <cfloat>
#include <chrono>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <ios>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <streambuf>
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;

#define rep(i,n) for (int i=0; i<(int)(n); i++)
#define minv(v) *min_element(v.begin(), v.end())
#define maxv(v) *max_element(v.begin(), v.end())
#define sortvv(myVec) sort(myVec.begin(),myVec.end(),[](const vector<int> &alpha,const vector<int> &beta){return alpha[0] < beta[0];})
#define append(v,d) v.push_back(d)
#define append2(v,i,d) v[i].push_back(d)

template <typename T>
using vec = vector<T>;
template <typename T>
using vv = vector<vector<T>>;
template <typename T>
using heapq = priority_queue<T>;

template <typename Type>
Type sumv(const vector<Type>& v){
    Type sum = 0;
    for(size_t i=0; i<v.size(); i++){
        sum += v[i];
    }
    return sum;
}

template <typename Type>
Type pow(Type x, Type n,Type mod) {
    Type ret = 1;
    while (n > 0) {
        if (n & 1) ret = ret * x % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return ret;
}


struct Edge {
    long long to;
    long long cost;
};
using Graph = vector<vector<Edge>>;
using P = pair<long, int>;
const long long INF = 1LL << 60;

/* dijkstra(G,s,dis)
    入力：グラフ G, 開始点 s, 距離を格納する dis
    計算量：O(|E|log|V|)
    副作用：dis が書き換えられる
*/
void dijkstra(const Graph &G, int s, vector<long long> &dis) {
    int N = G.size();
    dis.resize(N, pow(10,16));
    priority_queue<P, vector<P>, greater<P>> pq;  // 「仮の最短距離, 頂点」が小さい順に並ぶ
    dis[s] = 0;
    pq.emplace(dis[s], s);
    while (!pq.empty()) {
        P p = pq.top();
        pq.pop();
        int v = p.second;
        if (dis[v] < p.first) {  // 最短距離で無ければ無視
            continue;
        }
        for (auto &e : G[v]) {
            if (dis[e.to] > dis[v] + e.cost) {  // 最短距離候補なら priority_queue に追加
                dis[e.to] = dis[v] + e.cost;
                pq.emplace(dis[e.to], e.to);
            }
        }
    }
}

struct Eratosthenes {
    // テーブル
    vector<bool> isprime;

    // 整数 i を割り切る最小の素数
    vector<int> minfactor;

    // コンストラクタで篩を回す
    Eratosthenes(int N) : isprime(N+1, true),
                          minfactor(N+1, -1) {
        // 1 は予めふるい落としておく
        isprime[1] = false;
        minfactor[1] = 1;

        // 篩
        for (int p = 2; p <= N; ++p) {
            // すでに合成数であるものはスキップする
            if (!isprime[p]) continue;

            // p についての情報更新
            minfactor[p] = p;

            // p 以外の p の倍数から素数ラベルを剥奪
            for (int q = p * 2; q <= N; q += p) {
                // q は合成数なのでふるい落とす
                isprime[q] = false;

                // q は p で割り切れる旨を更新
                if (minfactor[q] == -1) minfactor[q] = p;
            }
        }
    }

    // 高速素因数分解
    // pair (素因子, 指数) の vector を返す
    vector<pair<int,int>> factorize(int n) {
        vector<pair<int,int>> res;
        while (n > 1) {
            int p = minfactor[n];
            int exp = 0;

            // n で割り切れる限り割る
            while (minfactor[n] == p) {
                n /= p;
                ++exp;
            }
            res.emplace_back(p, exp);
        }
        return res;
    }  
};

long long modinv(long long a, long long m) {
    long long b = m, u = 1, v = 0;
    while (b) {
        long long t = a / b;
        a -= t * b; swap(a, b);
        u -= t * v; swap(u, v);
    }
    u %= m;
    if (u < 0) u += m;
    return u;
}

/**
vv<int> a(x,vec<int>(y));
**/

int main(){
    int n;
    string s;
    cin>>n;
    cin>>s;
    vec<int> cnt(3,0);
    vv<int> l(n,vec<int>(3,0));
    vec<int> r2;
    vec<int> g2;
    vec<int> b2;
    rep(i,n){
        l[i][0]=cnt[0];
        l[i][1]=cnt[1];
        l[i][2]=cnt[2];
        if (s[i]=='R'){
            cnt[0]+=1;
            r2.push_back(i);
        }else if(s[i]=='G'){
            cnt[1]+=1;
            g2.push_back(i);
        }else{
            cnt[2]+=1;
            b2.push_back(i);
        }
    }
    int r=cnt[0],g=cnt[1],b=cnt[2];
    int inf=1000000;
    vec<vec<vec<vec<int>>>> dp(3,vec<vec<vec<int>>>(r+1,vec<vec<int>>(g+1,vec<int>(b+1,inf))));
    dp[0][0][0][0]=0;
    dp[1][0][0][0]=0;
    dp[2][0][0][0]=0;
    rep(i,r+1){
        rep(j,g+1){
            rep(k,b+1){
                if (i!=r){
                    dp[0][i+1][j][k]=min(dp[0][i+1][j][k],min(dp[1][i][j][k],dp[2][i][j][k])+max(0,l[r2[i]][1]-j)+max(0,l[r2[i]][2]-k));
                }
                if (j!=g){
                    dp[1][i][j+1][k]=min(dp[1][i][j+1][k],min(dp[0][i][j][k],dp[2][i][j][k])+max(0,l[g2[j]][0]-i)+max(0,l[g2[j]][2]-k));
                }
                if (k!=b){
                    dp[2][i][j][k+1]=min(dp[2][i][j][k+1],min(dp[0][i][j][k],dp[1][i][j][k])+max(0,l[b2[k]][0]-i)+max(0,l[b2[k]][1]-j));
                }
            }
        }
    }
    int ans=min(dp[0][r][g][b],min(dp[1][r][g][b],dp[2][r][g][b]));
    if (ans==inf){
        cout<<-1<<endl;
    }else{
        cout<<ans<<endl;
    }
}
accuracy: 1
time_ms: 30
memory_kb: 44124
final_rank: 5

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
constexpr int INF = 0x3f3f3f3f;
constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr double EPS = 1e-8;
constexpr int MOD = 1000000007;
// constexpr int MOD = 998244353;
constexpr int DY[]{1, 0, -1, 0}, DX[]{0, -1, 0, 1};
constexpr int DY8[]{1, 1, 0, -1, -1, -1, 0, 1}, DX8[]{0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
struct IOSetup {
  IOSetup() {
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    std::cout << fixed << setprecision(20);
  }
} iosetup;

int main() {
  constexpr int C = 3;
  int n; string s; cin >> n >> s;
  vector<int> t(n);
  REP(i, n) {
    switch (s[i]) {
      case 'R':
        t[i] = 0;
        break;
      case 'G':
        t[i] = 1;
        break;
      case 'Y':
        t[i] = 2;
        break;
    }
  }
  vector<int> pos[C]{};
  REP(i, n) pos[t[i]].emplace_back(i);
  vector left(n, vector(C, 0));
  REP(i, n) REP(j, i) ++left[i][t[j]];
  int num[C]{};
  REP(i, C) num[i] = pos[i].size();
  vector dp(1, vector(1, vector(C + 1, INF)));
  dp[0][0][C] = 0;
  REP(i, n) {
    const int pa = dp.size(), pb = dp.front().size();
    const int a = min(i / 2 + 1, num[0]), b = min(i / 2 + 1, num[1]);
    vector nx(a + 1, vector(b + 1, vector(C, INF)));
    REP(x, pa) REP(y, pb) {
      if (x + y > i) continue;
      const int z = i - (x + y);
      if (z > num[2]) continue;
      int pat[C]{INF, INF, INF};
      for (int p = 0; p < (i == 0 ? C + 1 : C); ++p) REP(q, C) {
        if (q != p) chmin(pat[q], dp[x][y][p]);
      }
      if (x + 1 <= a) {
        chmin(nx[x + 1][y][0], pat[0] + max(y - left[pos[0][x]][1], 0) + max(z - left[pos[0][x]][2], 0));
      }
      if (y + 1 <= b) {
        chmin(nx[x][y + 1][1], pat[1] + max(z - left[pos[1][y]][2], 0) + max(x - left[pos[1][y]][0], 0));
      }
      if (z + 1 <= num[2]) {
        chmin(nx[x][y][2], pat[2] + max(x - left[pos[2][z]][0], 0) + max(y - left[pos[2][z]][1], 0));
      }
    }
    dp.swap(nx);
  }
  if (dp.size() < num[0] + 1 || dp.front().size() < num[1] + 1) {
    cout << "-1\n";
    return 0;
  }
  const int ans = *min_element(ALL(dp[num[0]][num[1]]));
  cout << (ans == INF ? -1 : ans) << '\n';
  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 8096
final_rank: 7

code_snippet: #include <iostream>
#include <numeric>
#include <algorithm>
#include <vector>

using namespace std;

constexpr int INF = 1 << 30;

void solve() {
    int n;
    cin >> n;

    vector<vector<int>> xss(3);
    for (int i = 0; i < n; ++i) {
        char c;
        cin >> c;
        for (int j = 0; j < 3; ++j) {
            if (c == "RGY"[j]) xss[j].push_back(i);
        }
    }

    vector<int> ns(3);
    for (int c = 0; c < 3; ++c) ns[c] = xss[c].size();

    auto cnt = vector(3, vector(n + 1, vector(n + 1, 0)));
    // [0, i)を除外したとき、j未満はいくつあるか
    for (int c = 0; c < 3; ++c) {
        for (int i = 0; i <= ns[c]; ++i) {
            for (int j = i; j < ns[c]; ++j) {
                ++cnt[c][i][xss[c][j] + 1];
            }
            partial_sum(cnt[c][i].begin(), cnt[c][i].end(),
                        cnt[c][i].begin());
        }
    }

    auto dp = vector(ns[0] + 1, vector(ns[1] + 1, vector(ns[2] + 1, vector(3, INF))));
    fill(dp[0][0][0].begin(), dp[0][0][0].end(), 0);

    vector<int> is(3);
    for (is[0] = 0; is[0] <= ns[0]; ++is[0]) {
        for (is[1] = 0; is[1] <= ns[1]; ++is[1]) {
            for (is[2] = 0; is[2] <= ns[2]; ++is[2]) {
                for (int pc = 0; pc < 3; ++pc) {
                    int p = dp[is[0]][is[1]][is[2]][pc];

                    for (int nc = 0; nc < 3; ++nc) {
                        if (nc == pc || is[nc] == ns[nc]) continue;

                        int d = 0;
                        for (int c = 0; c < 3; ++c) {
                            d += cnt[c][is[c]][xss[nc][is[nc]]];
                        }

                        ++is[nc];
                        dp[is[0]][is[1]][is[2]][nc] = min(dp[is[0]][is[1]][is[2]][nc], p + d);
                        --is[nc];
                    }
                }
            }
        }
    }

    int ans = *min_element(dp[ns[0]][ns[1]][ns[2]].begin(), dp[ns[0]][ns[1]][ns[2]].end());
    cout << (ans == INF ? -1 : ans) << "\n";
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    solve();

    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 139156
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using UL = unsigned int;
using ULL = unsigned long long;
using LL = long long;
#define rep(i,n) for(UL i=0; i<(n); i++)

UL N;
char S[401];
UL V[401];
vector<UL> R,G,Y;
UL D[251][251][251][3];
UL dp[251][251][251][3];

int main(){
 scanf("%u",&N);
 scanf(" ");
 scanf("%s",S);
 rep(i,N){
  if(S[i]=='R'){ V[i]=R.size(); R.push_back(i); }
  if(S[i]=='G'){ V[i]=G.size(); G.push_back(i); }
  if(S[i]=='Y'){ V[i]=Y.size(); Y.push_back(i); }
 }
 rep(i,N) if(V[i]>200){ printf("-1\n"); return 0; }
 rep(iR,R.size()+1) rep(iG,G.size()+1) rep(iY,Y.size()+1) rep(j,3)
  D[iR][iG][iY][j]=N;
 for(UL i=N-1; i!=~0u; i--){
  if(S[i]=='R'){
   rep(iG,G.size()+1) rep(iY,Y.size()+1){
    rep(j,3) D[V[i]][iG][iY][j] = D[V[i]+1][iG][iY][j];
    D[V[i]][iG][iY][0] = V[i]+iG+iY;
   }
  }
  if(S[i]=='G'){
   rep(iR,R.size()+1) rep(iY,Y.size()+1){
    rep(j,3) D[iR][V[i]][iY][j] = D[iR][V[i]+1][iY][j];
    D[iR][V[i]][iY][1] = iR+V[i]+iY;
   }
  }
  if(S[i]=='Y'){
   rep(iR,R.size()+1) rep(iG,G.size()+1){
    rep(j,3) D[iR][iG][V[i]][j] = D[iR][iG][V[i]+1][j];
    D[iR][iG][V[i]][2] = iR+iG+V[i];
   }
  }
 }

 rep(iR,R.size()+1) rep(iG,G.size()+1) rep(iY,Y.size()+1) rep(j,3)
  dp[iR][iG][iY][j]=(~0u)>>1;
 rep(j,3) dp[0][0][0][j] = 0;
 rep(iR,R.size()+1) rep(iG,G.size()+1) rep(iY,Y.size()+1){
  UL p=iR+iG+iY;
  if(iR) dp[iR][iG][iY][0] = min(dp[iR-1][iG][iY][1],dp[iR-1][iG][iY][2])+D[iR-1][iG][iY][0]-p+1;
  if(iG) dp[iR][iG][iY][1] = min(dp[iR][iG-1][iY][0],dp[iR][iG-1][iY][2])+D[iR][iG-1][iY][1]-p+1;
  if(iY) dp[iR][iG][iY][2] = min(dp[iR][iG][iY-1][0],dp[iR][iG][iY-1][1])+D[iR][iG][iY-1][2]-p+1;
 }
 UL ans = (~0u)>>1;
 rep(j,3) ans = min(ans,dp[R.size()][G.size()][Y.size()][j]);
 if(ans==(~0u)>>1) printf("-1\n");
 else printf("%u\n",ans);
 return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 241384
final_rank: 19

code_snippet: #include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 400;
const int INFV = 1001001001;

int N;
char S[MAXN + 1]; int A[MAXN];
int dp[MAXN + 1][MAXN + 1][MAXN + 1][3];
int cnts[3], locs[3][MAXN], prevs[3][MAXN];

void chmin(int& x, int y)
{
    x = min(x, y);
}

int main()
{
    scanf("%d%s", &N, S);

    for (int i = 0; i < N; ++i) {
        switch (S[i]) {
            case 'R': A[i] = 0; break;
            case 'G': A[i] = 1; break;
            case 'Y': A[i] = 2; break;
        }
    }

    for (int i = 0; i < 3; ++i) cnts[i] = 0;
    for (int i = 0; i < N; ++i) {
        locs[A[i]][cnts[A[i]]++] = i;
        for (int j = 0; j < 3; ++j) prevs[j][i] = cnts[j];
    }

    for (int a = 0; a <= cnts[0]; ++a) {
        for (int b = 0; b <= cnts[1]; ++b) {
            for (int c = 0; c <= cnts[2]; ++c) {
                for (int s = 0; s < 3; ++s) {
                    dp[a][b][c][s] = INFV;
                }
            }
        }
    }

    dp[0][0][0][0] = dp[0][0][0][1] = dp[0][0][0][2] = 0;

    for (int a = 0; a <= cnts[0]; ++a) {
        for (int b = 0; b <= cnts[1]; ++b) {
            for (int c = 0; c <= cnts[2]; ++c) {
                for (int s = 0; s < 3; ++s) {
                    if (s != 0 && a < cnts[0]) {
                        int p = locs[0][a];
                        chmin(dp[a + 1][b][c][0], dp[a][b][c][s] + max(0, prevs[1][p] - b) + max(0, prevs[2][p] - c));
                    }
                    if (s != 1 && b < cnts[1]) {
                        int p = locs[1][b];
                        chmin(dp[a][b + 1][c][1], dp[a][b][c][s] + max(0, prevs[0][p] - a) + max(0, prevs[2][p] - c));
                    }
                    if (s != 2 && c < cnts[2]) {
                        int p = locs[2][c];
                        chmin(dp[a][b][c + 1][2], dp[a][b][c][s] + max(0, prevs[0][p] - a) + max(0, prevs[1][p] - b));
                    }
                }
            }
        }
    }

    int ret = min({ dp[cnts[0]][cnts[1]][cnts[2]][0], dp[cnts[0]][cnts[1]][cnts[2]][1], dp[cnts[0]][cnts[1]][cnts[2]][2] });
    if (ret >= INFV) ret = -1;
    printf("%d\n", ret);

    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 164692
final_rank: 13

code_snippet: #include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

int main(){
  int N;
  cin >> N;
  vector<int> S(N);
  vector<vector<int>> I(3);
  vector<vector<int>> cnt(N,vector<int>(3));
  {
    string s;
    cin >> s;
    map<char,int> R;
    R['R'] = 0;
    R['G'] = 1;
    R['Y'] = 2;
    for(int i = 0; i < N; ++i){
      S[i] = R[s[i]];
      I[S[i]].push_back(i);
      ++cnt[i][S[i]];
    }
    for(int i = 1; i < N; ++i){
      for(int j = 0; j < 3; ++j)
        cnt[i][j] += cnt[i-1][j];
    }
  }
  int r = I[0].size(), g = I[1].size(), b = I[2].size();
  int sz[] = {r,g,b};
  for(int i = 0; i < 3; ++i)
    I[i].push_back(N);
  const int INF = 1e9;
  vector<vector<vector<vector<int>>>> dp(r+1,vector<vector<vector<int>>>(g+1,vector<vector<int>>(b+1,vector<int>(3,INF))));
  for(int i = 0; i < 3; ++i)
    dp[0][0][0][i] = 0;

  for(int i = 0; i <= r; ++i){
    for(int j = 0; j <= g; ++j){
      for(int k = 0; k <= b; ++k){
        for(int l = 0; l < 3; ++l){
          if(dp[i][j][k][l] >= INF) continue;
          for(int m = 0; m < 3; ++m){
            vector<int> tmp = {i,j,k};
            if(tmp[m] >= sz[m]) continue;
            if(l == m) continue;
            int idx = I[m][tmp[m]];
            int c = 0;
            for(int n = 0; n < 3; ++n){
              if(n == m) continue;
              c += max(0,cnt[idx][n] - tmp[n]);
            }
            ++tmp[m];
            auto& lv = dp[tmp[0]][tmp[1]][tmp[2]][m];
            lv = min(lv,dp[i][j][k][l]+c);
          }
        }
      }
    }
  }
  int ans = INF;
  for(int i = 0; i < 3; ++i)
    ans = min(ans,dp[r][g][b][i]);
  if(ans >= INF) ans = -1;
  cout << ans << endl;
}
accuracy: 1
time_ms: 370
memory_kb: 137352
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int N = 410, INF = 1 << 29;
char s[N];
int a[N], cnt[N][3], ord[3][N];
int dp[N][N][3], tmp[N][N][3];
int mp[256];
int main() {
    mp['R'] = 0;
    mp['Y'] = 1;
    mp['G'] = 2;
    int n;
    scanf("%d%s", &n, s + 1);
    for (int i = 1; i <= n; ++i) {
        a[i] = mp[s[i]];
        for (int j = 0; j < 3; ++j) cnt[i][j] = cnt[i - 1][j] + (a[i] == j);
        ord[a[i]][cnt[i][a[i]]] = i;
    }
    fill(**dp, dp[N - 1][N - 1] + 3, INF);
    dp[0][0][0] = dp[0][0][1] = dp[0][0][2] = 0;
    int n0 = cnt[n][0], n1 = cnt[n][1], n2 = cnt[n][2];
    for (int i = 0; i < n; ++i) {
        memcpy(tmp, dp, sizeof(tmp));
        fill(**dp, dp[N - 1][N - 1] + 3, INF);
        for (int r0 = 0; r0 <= n0; ++r0)
            for (int r1 = 0; r1 <= n1; ++r1) {
                int r2 = i - r0 - r1;
                if (r2 > n2 || r2 < 0)
                    continue;
                for (int f = 0; f < 3; ++f) {
                    for (int t = 0; t < 3; ++t) {
                        if (t == f)
                            continue;
                        int q0 = r0 + (t == 0), q1 = r1 + (t == 1), q2 = r2 + (t == 2);
                        if (q0 > n0 || q1 > n1 || q2 > n2)
                            continue;
                        int cdp = tmp[r0][r1][f];
                        static int qa[3];
                        qa[0] = q0;
                        qa[1] = q1;
                        qa[2] = q2;
                        int pos = ord[t][qa[t]];
                        for (int j = 0; j < 3; ++j) cdp += max(0, cnt[pos][j] - qa[j]);
                        dp[q0][q1][t] = min(dp[q0][q1][t], cdp);
                    }
                }
            }
    }
    int ans = *min_element(dp[n0][n1], dp[n0][n1] + 3);
    printf("%d\n", ans < INF ? ans : -1);
    return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 7236
final_rank: 9

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

string S;
vector<int> V[3];
int N, A[409], D[3][409];
int dp[409][409][409][3];

int main() {
	cin >> N >> S;
	for (int i = 0; i < S.size(); i++) {
		if (S[i] == 'R') A[i] = 0;
		if (S[i] == 'G') A[i] = 1;
		if (S[i] == 'Y') A[i] = 2;
		D[A[i]][i + 1] = 1;
		V[A[i]].push_back(i);
	}
	for (int i = 1; i <= N; i++) {
		D[0][i] += D[0][i - 1];
		D[1][i] += D[1][i - 1];
		D[2][i] += D[2][i - 1];
	}

	for (int i = 0; i <= D[0][N]; i++) {
		for (int j = 0; j <= D[1][N]; j++) {
			for (int k = 0; k <= D[2][N]; k++) {
				dp[i][j][k][0] = 1000000;
				dp[i][j][k][1] = 1000000;
				dp[i][j][k][2] = 1000000;
			}
		}
	}

	dp[0][0][0][0] = 0;
	dp[0][0][0][1] = 0;
	dp[0][0][0][2] = 0;
	for (int i = 0; i <= D[0][N]; i++) {
		for (int j = 0; j <= D[1][N]; j++) {
			for (int k = 0; k <= D[2][N]; k++) {
				if (i < D[0][N]) {
					int S1 = max(0, D[1][V[0][i]] - j);
					int S2 = max(0, D[2][V[0][i]] - k);
					dp[i + 1][j][k][0] = min(dp[i + 1][j][k][0], dp[i][j][k][1] + S1 + S2);
					dp[i + 1][j][k][0] = min(dp[i + 1][j][k][0], dp[i][j][k][2] + S1 + S2);
				}
				if (j < D[1][N]) {
					int S1 = max(0, D[0][V[1][j]] - i);
					int S2 = max(0, D[2][V[1][j]] - k);
					dp[i][j + 1][k][1] = min(dp[i][j + 1][k][1], dp[i][j][k][0] + S1 + S2);
					dp[i][j + 1][k][1] = min(dp[i][j + 1][k][1], dp[i][j][k][2] + S1 + S2);
				}
				if (k < D[2][N]) {
					int S1 = max(0, D[0][V[2][k]] - i);
					int S2 = max(0, D[1][V[2][k]] - j);
					dp[i][j][k + 1][2] = min(dp[i][j][k + 1][2], dp[i][j][k][0] + S1 + S2);
					dp[i][j][k + 1][2] = min(dp[i][j][k + 1][2], dp[i][j][k][1] + S1 + S2);
				}
			}
		}
	}

	int c0 = dp[D[0][N]][D[1][N]][D[2][N]][0];
	int c1 = dp[D[0][N]][D[1][N]][D[2][N]][1];
	int c2 = dp[D[0][N]][D[1][N]][D[2][N]][2];
	int val = min({ c0, c1, c2 });
	if (val == 1000000) cout << "-1" << endl;
	else cout << val << endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 165148
final_rank: 12

code_snippet: // #pragma GCC target("avx")  // CPU 処理並列化
// #pragma GCC optimize("O3")  // CPU 処理並列化
// #pragma GCC optimize("unroll-loops")  // 条件処理の呼び出しを減らす
// #define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
// #define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<deque>
#include<stack>
#include<string>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<stdlib.h>
#include<cassert>
#include<time.h>
#include<bitset>
#include<numeric>
#include<unordered_set>
#include<unordered_map>
#include<complex>
using namespace std;
const long long mod=1000000007;
const long long inf=mod*mod;
const long long d2=(mod+1)/2;
const long double EPS=1e-20;
const double INF=1e+10;
const double PI=acos(-1.0);
const int C_SIZE = 3100000;
const int UF_SIZE = 4100000;
namespace{
	long long fact[C_SIZE];
	long long finv[C_SIZE];
	long long inv[C_SIZE];
	long long Comb(int a,int b){
	 	if(a<b||b<0)return 0;
	 	return fact[a]*finv[b]%mod*finv[a-b]%mod;
	}
	void init_C(int n){
		fact[0]=finv[0]=inv[1]=1;
		for(int i=2;i<n;i++){
			inv[i]=(mod-(mod/i)*inv[mod%i]%mod)%mod;
		}
		for(int i=1;i<n;i++){
			fact[i]=fact[i-1]*i%mod;
			finv[i]=finv[i-1]*inv[i]%mod;
		}
	}
	long long pw(long long a,long long b){
		if(a<0LL)return 0;
		if(b<0LL)return 0;
		long long ret=1;
		while(b){
			if(b%2)ret=ret*a%mod;
			a=a*a%mod;
			b/=2;
		}
		return ret;
	}
	long long pw_mod(long long a,long long b,long long M){
		if(a<0LL)return 0;
		if(b<0LL)return 0;
		long long ret=1;
		while(b){
			if(b%2)ret=ret*a%M;
			a=a*a%M;
			b/=2;
		}
		return ret;
	}
	int pw_mod_int(int a,int b,int M){
		if(a<0)return 0;
		if(b<0)return 0;
		int ret=1;
		while(b){
			if(b%2)ret=(long long)ret*a%M;
			a=(long long)a*a%M;
			b/=2;
		}
		return ret;
	}
	int ABS(int a){return max(a,-a);}
	long long ABS(long long a){return max(a,-a);}
	double ABS(double a){return max(a,-a);}
	int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
	int UF[UF_SIZE];
	void init_UF(int n){
		for(int i=0;i<n;i++)UF[i]=-1;
	}
	int FIND(int a){
		if(UF[a]<0)return a;
		return UF[a]=FIND(UF[a]);
	}
	void UNION(int a,int b){
		a=FIND(a);b=FIND(b);if(a==b)return;
		if(UF[a]>UF[b])swap(a,b);
		UF[a]+=UF[b];UF[b]=a;
	}
}
// ここから編集しろ
char in[410];
int dp[2][410][410][3];
int ct[410][3];
int r[410];
int g[410];
int y[410];
int main(){
	int a;scanf("%d%s",&a,in);
	int R=0;
	int G=0;
	int Y=0;

	for(int i=0;i<a;i++){
		if(in[i]=='R'){r[R++]=i;}
		else if(in[i]=='G'){g[G++]=i;}
		else {y[Y++]=i;}
		ct[i+1][0]=R;
		ct[i+1][1]=G;
		ct[i+1][2]=Y;
	}
	for(int i=0;i<2;i++)for(int j=0;j<410;j++)for(int k=0;k<410;k++)for(int l=0;l<3;l++)
		dp[i][j][k][l]=mod;
	dp[0][0][0][0]=dp[0][0][0][1]=dp[0][0][0][2]=0;
	for(int i=0;i<a;i++){
		int t=i%2;
		for(int j=0;j<=R;j++)for(int k=0;k<=G;k++)for(int l=0;l<3;l++)dp[!t][j][k][l]=mod;
		for(int j=0;j<=R;j++)for(int k=0;k<=G;k++)for(int l=0;l<3;l++){
			if(dp[t][j][k][l]==mod)continue;
			// printf("%d %d %d %d: %d\n",i,j,k,l,dp[t][j][k][l]);
			if(l!=0&&j<R){
				int toc=dp[t][j][k][l];
				int at=r[j];
				toc+=max(0,ct[at][1]-k);
				toc+=max(0,ct[at][2]-(i-j-k));
				dp[!t][j+1][k][0]=min(dp[!t][j+1][k][0],toc);
			}
			if(l!=1&&k<G){
				int toc=dp[t][j][k][l];
				int at=g[k];
				toc+=max(0,ct[at][0]-j);
				toc+=max(0,ct[at][2]-(i-j-k));
				dp[!t][j][k+1][1]=min(dp[!t][j][k+1][1],toc);
			}
			if(l!=2&&(i-j-k)<Y){
				int toc=dp[t][j][k][l];
				int at=y[i-j-k];
				toc+=max(0,ct[at][0]-j);
				toc+=max(0,ct[at][1]-k);
				dp[!t][j][k][2]=min(dp[!t][j][k][2],toc);
			}
		}
	}
	int ret=mod;
	for(int i=0;i<3;i++)ret=min(ret,dp[a%2][R][G][i]);
	if(ret==mod)ret=-1;
	printf("%d\n",ret);
}
accuracy: 1
time_ms: 70
memory_kb: 6712
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;

ll N;
string S;

ll dp[401][401][401][3];

vector<ll> idx[3]; // R,G,Y;
vector<ll> back[3];

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    cin >> N >> S;

    back[0] = vector<ll>(N);
    back[1] = vector<ll>(N);
    back[2] = vector<ll>(N);

    back[0][N-1] = 0;
    back[1][N-1] = 0;
    back[2][N-1] = 0;

    if(S[N-1] == 'R') back[0][N-1] = 1;
    if(S[N-1] == 'G') back[1][N-1] = 1;
    if(S[N-1] == 'Y') back[2][N-1] = 1;

    for (int i = N-2;i >= 0;i--){
        for (int j = 0;j < 3;j++){
            back[j][i] = back[j][i+1];
        }
        if(S[i] == 'R') back[0][i]++;
        if(S[i] == 'G') back[1][i]++;
        if(S[i] == 'Y') back[2][i]++;
    }

    for (int i = 0;i < N;i++){
        if(S[i] == 'R') idx[0].push_back(i);
        if(S[i] == 'G') idx[1].push_back(i);
        if(S[i] == 'Y') idx[2].push_back(i);
    }

    for (int i = 0;i <= idx[0].size();i++){
        for (int j = 0;j <= idx[1].size();j++){
            for (int k = 0;k <= idx[2].size();k++){
                for (int l = 0;l < 3;l++){
                    dp[i][j][k][l] = LLONG_MAX;
                }
            }
        }
    }

    dp[0][0][0][0] = 0; //i,j,k:次の位置
    dp[0][0][0][1] = 0;
    dp[0][0][0][2] = 0;

    for (int i = 0;i <= idx[0].size();i++){
        for (int j = 0;j <= idx[1].size();j++){
            for (int k = 0;k <= idx[2].size();k++){
                for (int l = 0;l < 3;l++){
                    //cout << i << " " << j << " " << k << " " << dp[i][j][k] << endl;
                    if(dp[i][j][k][l] == LLONG_MAX) continue;
                    //cout << i << " " << j << " " << k << " " << dp[i][j][k][l] << endl;
                    if(i != idx[0].size() && l != 0)dp[i+1][j][k][0] = min(dp[i+1][j][k][0], dp[i][j][k][l]+max<ll>(idx[1].size()-j-back[1][idx[0][i]],0LL)+max<ll>(idx[2].size()-k-back[2][idx[0][i]],0LL));
                    if(j != idx[1].size() && l != 1)dp[i][j+1][k][1] = min(dp[i][j+1][k][1], dp[i][j][k][l]+max<ll>(idx[0].size()-i-back[0][idx[1][j]],0LL)+max<ll>(idx[2].size()-k-back[2][idx[1][j]],0LL));
                    if(k != idx[2].size() && l != 2)dp[i][j][k+1][2] = min(dp[i][j][k+1][2], dp[i][j][k][l]+max<ll>(idx[0].size()-i-back[0][idx[2][k]],0LL)+max<ll>(idx[1].size()-j-back[1][idx[2][k]],0LL));
                }
            }
        }
    }

    ll ans = min({ dp[idx[0].size()][idx[1].size()][idx[2].size()][0] ,dp[idx[0].size()][idx[1].size()][idx[2].size()][1], dp[idx[0].size()][idx[1].size()][idx[2].size()][2]});
    if(ans == LLONG_MAX) ans = -1;

    cout << ans << endl;

    return 0;

}
accuracy: 1
time_ms: 50
memory_kb: 166224
final_rank: 14

code_snippet: #include "bits/stdc++.h"

using namespace std;

int N,M,K,L,R,H,W;
//long long int N,M,K,L,R,H,W;

constexpr long long int MOD=1000000007;
//constexpr  int MOD=1000000007;
//constexpr int MOD=998244353;
//constexpr long long int MOD=998244353;

constexpr long double EPS=1e-8;

int dp[201][201][201][3];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	cin>>N;
	string s;
	cin>>s;
	vector<int>v;
	int one=0,two=0,zero=0;
	for(auto i:s){
		if(i=='R'){
			v.push_back(0);
			zero++;
		}
		else if(i=='G'){
			v.push_back(1);
			one++;
		}
		else {
			v.push_back(2);
			two++;
		}
	}
	if(zero>(N+1)/2||one>(N+1)/2||two>(N+1)/2){
		cout<<-1<<endl;
		return 0;
	}
	for(int i=0;i<=200;i++)for(int j=0;j<=200;j++)for(int k=0;k<200;k++)for(int l=0;l<3;l++)dp[i][j][k][l]=MOD;
	vector<pair<int,int>>oneP;
	vector<pair<int,int>>twoP;
	vector<pair<int,int>>zeroP;
	vector<int>oneplace;
	vector<int>twoplace;
	vector<int>zeroplace;
	int a=0,b=0,c=0;
	for(int i=0;i<N;i++){
		if(v[i]==1){
			oneP.push_back({c,b});
			oneplace.push_back(i);
			a++;
		}
		else if(v[i]==2){
			twoP.push_back({c,a});
			twoplace.push_back(i);
			b++;
		}
		else{
			zeroP.push_back({a,b});
			zeroplace.push_back(i);
			c++;
		}
	}
	if(one)dp[0][1][0][1]=oneplace[0];
	if(two)dp[0][0][1][2]=twoplace[0];
	if(zero)dp[1][0][0][0]=zeroplace[0];
	for(int i=0;i<=zero;i++){
		for(int j=0;j<=one;j++){
			for(int k=0;k<=two;k++){
				if(!i&&!j&&!k)continue;
				for(int l=0;l<3;l++){
					if(l!=0&&i<zero){
						dp[i+1][j][k][0]=min(dp[i+1][j][k][0],dp[i][j][k][l]+zeroplace[i]+max(0,j-zeroP[i].first)+max(0,k-zeroP[i].second)-i-j-k);
					}
					if(l!=1&&j<one){
						dp[i][j+1][k][1]=min(dp[i][j+1][k][1],dp[i][j][k][l]+oneplace[j]+max(0,i-oneP[j].first)+max(0,k-oneP[j].second)-i-j-k);
					}
					if(l!=2&&k<two){
						dp[i][j][k+1][2]=min(dp[i][j][k+1][2],dp[i][j][k][l]+twoplace[k]+max(0,i-twoP[k].first)+max(0,j-twoP[k].second)-i-j-k);
					}
				}
			}
		}
	}
	for(int i=0;i<=zero;i++){
		for(int j=0;j<=one;j++){
			for(int k=0;k<=two;k++){
				for(int l=0;l<3;l++){
				//	cout<<i<<" "<<j<<" "<<k<<" "<<l<<" "<<dp[i][j][k][l]<<endl;
				}
			}
		}
	}
	int ans=MOD;
	for(int i=0;i<3;i++)ans=min(ans,dp[zero][one][two][i]);
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 50
memory_kb: 98396
final_rank: 10

code_snippet: #include <bits/stdc++.h>
 
//    #include <boost/multiprecision/cpp_int.hpp>
 //#define int long long
 #define inf  1000000007
 #define pa pair<int,int>
 #define ll long long
 #define pal pair<double,double>
 #define ppap pair<pa,int>
  #define PI 3.14159265358979323846
  #define paa pair<int,char>
  #define  mp make_pair
  #define  pb push_back
  #define EPS (1e-8)
                                          
    int dx[8]={0,1,0,-1,1,1,-1,-1};
    int dy[8]={1,0,-1,0,-1,1,1,-1};
                                            using namespace std;
                                   			class pa3{
                                            	public:
                                            	int x;
                                   				int y,z;
                                            	pa3(int x=0,int y=0,int z=0):x(x),y(y),z(z) {}
                                            	bool operator < (const pa3 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		 return z<p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                   				bool operator > (const pa3 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		 return z>p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa3 &p) const{
                                            		return x==p.x && y==p.y && z==p.z;
                                            	}
                                            		bool operator != (const pa3 &p) const{
                                            			return !( x==p.x && y==p.y && z==p.z);
                                            	}
                                            
                                            };
                                            
                                            class pa4{
                                            	public:
                                            	int x;
                                            	int y,z,w;
                                            	pa4(int x=0,int y=0,int z=0,int w=0):x(x),y(y),z(z),w(w) {}
                                            	bool operator < (const pa4 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		if(z!=p.z)return z<p.z;
                                            		return w<p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator > (const pa4 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		if(z!=p.z)return z>p.z;
                                            		return w>p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa4 &p) const{
                                            		return x==p.x && y==p.y && z==p.z &&w==p.w;
                                            	}
                                            		
                                            
                                            };
                                            class pa2{
                                            	public:
                                            	int x,y;
                                            	pa2(int x=0,int y=0):x(x),y(y) {}
                                            	pa2 operator + (pa2 p) {return pa2(x+p.x,y+p.y);}
                                            	pa2 operator - (pa2 p) {return pa2(x-p.x,y-p.y);}
                                            	bool operator < (const pa2 &p) const{
                                            		return y != p.y ? y<p.y: x<p.x;
                                            	}
                                            	bool operator > (const pa2 &p) const{
                                            		return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa2 &p) const{
                                            		return abs(x-p.x)==0 && abs(y-p.y)==0;
                                            	}
                                            	bool operator != (const pa2 &p) const{
                                            		return !(abs(x-p.x)==0 && abs(y-p.y)==0);
                                            	}
                                            		
                                            
                                            };
                                            
 
                      
                                string itos( int i ) {
                                ostringstream s ;
                                s << i ;
                                return s.str() ;
                                }
                                 
                                int gcd(int v,int b){
                                	if(v==0) return b;
                                	if(b==0) return v;
                                	if(v>b) return gcd(b,v);
                                	if(v==b) return b;
                                	if(b%v==0) return v;
                                	return gcd(v,b%v);
                                }
                 
                            
                                int mod;
int extgcd(int a, int b, int &x, int &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    int d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
pa operator+(const pa & l,const pa & r) {   
    return {l.first+r.first,l.second+r.second};                                    
}    
pa operator-(const pa & l,const pa & r) {   
    return {l.first-r.first,l.second-r.second};                                    
}  
                                
                int pr[10000100];
                int inv[10000010];
                
                int beki(int wa,int rr,int warukazu){
                	if(rr==0) return 1%warukazu;
                	if(rr==1) return wa%warukazu;
                	wa%=warukazu;
                	if(rr%2==1) return ((ll)beki(wa,rr-1,warukazu)*(ll)wa)%warukazu;
                	ll zx=beki(wa,rr/2,warukazu);
                	return (zx*zx)%warukazu;
                }
 
                
    			int comb(int nn,int rr){
    				if(rr<0 || rr>nn || nn<0) return 0;
    				int r=pr[nn]*inv[rr];
    				r%=mod;
    				r*=inv[nn-rr];
    				r%=mod;
    				return r;
    			}
               
                void gya(int ert){
                	pr[0]=1;
                	for(int i=1;i<=ert;i++){
                		pr[i]=(pr[i-1]*i)%mod;
                	}
                		inv[ert]=beki(pr[ert],mod-2,mod);
                	for(int i=ert-1;i>=0;i--){
                		inv[i]=inv[i+1]*(i+1)%mod;
                	}
                }
                
              //   cin.tie(0);
    		//	ios::sync_with_stdio(false);
    			//priority_queue<pa3,vector<pa3>,greater<pa3>> pq;            
                 //sort(ve.begin(),ve.end(),greater<int>());
 //   mt19937(clock_per_sec);
  //  mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()) ;
      

int dp[410][410][410][3];
string s;

int memo[410][3]={};
vector<int> ve[3];

int solve(int a,int b,int c,int t){
	if(a<0 || b<0 || c<0) return inf;
	if(a==0 && b==0 && c==0) return 0;
	if(dp[a][b][c][t]>=0) return dp[a][b][c][t];
	if(t==0 && a==0)dp[a][b][c][t]=inf;
	if(t==1 && b==0)dp[a][b][c][t]=inf;
	if(t==2 && c==0)dp[a][b][c][t]=inf;
	if(dp[a][b][c][t]>=0) return dp[a][b][c][t];
	int p=inf,q=inf;
	if(t==0)if(a>=1){
		int T=max(0,memo[ve[0][a-1]][2]-c)+max(0,memo[ve[0][a-1]][1]-b);
		p=solve(a-1,b,c,1)+T;
		q=solve(a-1,b,c,2)+T;
		
	}
	if(t==1)if(b>=1){
		int T=max(0,memo[ve[1][b-1]][0]-a)+max(0,memo[ve[1][b-1]][2]-c);
		if(b>=1)p=solve(a,b-1,c,0)+T;
		if(b>=1)q=solve(a,b-1,c,2)+T;
	}
	if(t==2)if(c>=1){
		int T=max(0,memo[ve[2][c-1]][0]-a)+max(0,memo[ve[2][c-1]][1]-b);
		if(c>=1)p=solve(a,b,c-1,0)+T;
		if(c>=1)q=solve(a,b,c-1,1)+T;
	}
	//cout<<a<<" "<<b<<" "<<c<<" "<<t<<"   "<<p<<" "<<q<<endl;
	p=min(p,inf);
dp[a][b][c][t]=min(p,q);
return min(p,q);
	
	
	
}

signed main(){
	
	
   cin.tie(0);
	ios::sync_with_stdio(false);
	int n;
	cin>>n;
	cin>>s;
	
	int t1=0,t2=0,t3=0;
	int yy=0;
	for(auto c:s){
		t1+=c=='R';
		t2+=c=='G';
		t3+=c=='Y';
		if(c=='R')memo[yy][0]++,ve[0].pb(yy);
		if(c=='G')memo[yy][1]++,ve[1].pb(yy);
		if(c=='Y')memo[yy][2]++,ve[2].pb(yy);
		yy++;
	}
	for(int i=1;i<n;i++)for(int j=0;j<3;j++)memo[i][j]+=memo[i-1][j];
	
	for(int i=0;i<=t1;i++)for(int j=0;j<=t2;j++)for(int k=0;k<=t3;k++)for(int h=0;h<3;h++)dp[i][j][k][h]=-1;
	
		int y=min({solve(t1,t2,t3,0),solve(t1,t2,t3,1),solve(t1,t2,t3,2)});
	if(y>=inf)cout<<-1<<endl;
	else cout<<y<<endl;
	
	return 0;
	

 
 }
accuracy: 1
time_ms: 70
memory_kb: 165164
final_rank: 16

code_snippet: #include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace std;

static_assert(sizeof(long) == 8, "long must be 64-bit.");

int sindex(const string& S, char c, int start = 0)
{
    for (int i = start; ; ++i)
        if (S[i] == c)
            return i;
}

void set_min(int& a, int v)
{
    if (a > v)
        a = v;
}

int solve(int N, const string& S)
{
    const int INF = (N + 1) * (N + 1);

    int cr = 0, cg = 0, cy = 0;
    for (char c : S) {
        switch (c) {
        case 'R':
            ++cr;
            break;
        case 'G':
            ++cg;
            break;
        case 'Y':
            ++cy;
            break;
        }
    }

    vector<vector<vector<array<int, 3>>>> move_table(
        cr + 1, vector<vector<array<int, 3>>>(
            cg + 1, vector<array<int, 3>>(
                cy + 1)));
    for (int ur = 0; ur <= cr; ++ur) {
        for (int ug = 0; ug <= cg; ++ug) {
            string B;
            int rr = ur;
            int rg = ug;
            for (char c : S) {
                if (c == 'R' && rr > 0) {
                    --rr;
                } else if (c == 'G' && rg > 0) {
                    --rg;
                } else {
                    B.push_back(c);
                }
            }
            int lenb = (int)B.size();
            int ri = ur < cr ? sindex(B, 'R') : lenb;
            int gi = ug < cg ? sindex(B, 'G') : lenb;
            int yi = cy > 0 ? sindex(B, 'Y') : lenb;

            int roff = 0, goff = 0, yoff = 0;

            for (int uy = 0; uy < cy; ++uy) {
                move_table[ur][ug][uy] = {
                    ri - roff,
                    gi - goff,
                    yi - yoff,
                };

                if (ri > yi)
                    ++roff;
                if (gi > yi)
                    ++goff;
                ++yoff;

                yi = uy < cy - 1 ? sindex(B, 'Y', yi + 1) : lenb;
            }

            move_table[ur][ug][cy] = {
                ri - roff,
                gi - goff,
                yi - yoff,
            };
        }
    }

    vector<vector<array<int, 3>>> dp(
        cr + 1, vector<array<int, 3>>(
            cg + 1, {INF, INF, INF}));
    dp[0][0] = {0, 0, 0};

    for (int ut = 0; ut < N; ++ut) {
        vector<vector<array<int, 3>>> ndp(
            cr + 1, vector<array<int, 3>>(
                cg + 1, {INF, INF, INF}));

        for (int ur = 0; ur <= min(ut, cr); ++ur) {
            int rest = ut - ur;
            for (int ug = min(rest, cg); ug >= 0; --ug) {
                int uy = ut - ur - ug;
                if (uy > cy)
                    break;
                for (int col = 0; col < 3; ++col) {
                    int dv = dp[ur][ug][col];
                    if (dv == INF)
                        continue;
                    if (ur < cr && col != 0) {
                        set_min(ndp[ur + 1][ug][0],
                                dv + move_table[ur][ug][uy][0]);
                    }
                    if (ug < cg && col != 1) {
                        set_min(ndp[ur][ug + 1][1],
                                dv + move_table[ur][ug][uy][1]);
                    }
                    if (uy < cy && col != 2) {
                        set_min(ndp[ur][ug][2],
                                dv + move_table[ur][ug][uy][2]);
                    }
                }
            }
        }

        dp.swap(ndp);
    }

    int ans = min(dp[cr][cg][0],
                  min(dp[cr][cg][1], dp[cr][cg][2]));
    if (ans == INF)
        return -1;
    return ans;
}

int main()
{
    int N;
    cin >> N;
    string S;
    cin >> S;
    cout << solve(N, S) << '\n';
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 32488
final_rank: 6