题意:
看原题吧不概括了。。
做法:
观察到
n
n
很小。考虑直接暴力,所有区间按照左端点排序,右端点用树状数组维护。
或者可以用位运算优化掉一个 。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int N = 50;
const int inf = 1e9;
int n, ans, tot;
int a[N], l[N], r[N];
struct bit {
int t[N];
inline void clr() { memset(t, 0, sizeof t); }
inline void add(int x, int v) { for(int i = x; i < N; i += i&-i) t[i] += v; }
inline int sum(int x) { int ret = 0; for(int i = x; i; i -= i&-i) ret += t[i]; return ret; }
inline int qry(int l, int r) { return sum(r) - sum(l-1); }
} up, dw;
inline void dfs(int k, int nans) {
if(nans > ans) return;
if(k > tot) { ans = nans; return; }
up.add(r[k], 1);
dfs(k+1, nans + min(up.qry(l[k], r[k]-1), up.qry(r[k]+1, n)+dw.qry(l[k]+1, n)));
up.add(r[k], -1);
dw.add(r[k], 1);
dfs(k+1, nans + min(dw.qry(l[k], r[k]-1), dw.qry(r[k]+1, n)+up.qry(l[k]+1, n)));
dw.add(r[k], -1);
}
int main() {
int test; scanf("%d", &test);
while(test --) {
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
tot = 0;
for(int i = 1; i <= n; i ++)
for(int j = i+1; j <= n; j ++)
if(a[i] == a[j]) { l[++ tot] = i; r[tot] = j; break; }
ans = inf; up.clr(); dw.clr();
dfs(1, 0);
printf("%d\n", ans);
}
return 0;
}