이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("Ofast")
#define int long long
using namespace std;
int f(int x){
return x * (x - 1) / 2;
}
const int G = 15;
const int N = 1e5 + 11;
int L[G][G][N], R[G][G][N];
int cL[G][N], cR[G][N];
int s0[G][G][N], s1[G][N];
int dp[1 << G];
int f(int mask, int j, int x){
int c = cL[j][x] + cR[j][x];
for(int k = 0; k < G; k++){
if(j != k && (mask & (1 << k))){
c += L[k][j][x] + R[k][j][x];
}
}
return c;
}
int g(int mask, int j, int x){
int c = s1[j][x];
for(int k = 0; k < G; k++){
if(j != k && (mask & (1 << k))){
c += s0[k][j][x];
}
}
return c;
}
int32_t main(){
string s; cin >> s;
int n = s.size();
for(int i = 0; i < G; i++){
for(int j = 0; j < G; j++){
// add char i then char j
L[i][j][0] = 0; int m = 0;
for(int k = 0; k < n; k++){
s0[i][j][k] += m;
if(s[k] == 'A' + i){
m += 2;
L[i][j][k + 1] = L[i][j][k];
}else if(s[k] == 'A' + j){
L[i][j][k + 1] = L[i][j][k] + m;
}else{
L[i][j][k + 1] = L[i][j][k];
}
}
R[i][j][n] = 0; m = 0;
for(int k = n - 1; k >= 0; k--){
s0[i][j][k] -= m;
if(s[k] == 'A' + i){
m += 2;
R[i][j][k] = R[i][j][k + 1];
}else if(s[k] == 'A' + j){
R[i][j][k] = R[i][j][k + 1] + m;
}else{
R[i][j][k] = R[i][j][k + 1];
}
}
}
}
for(int i = 0; i < G; i++){
cL[i][0] = 0; int m = 0;
for(int j = 0; j < n; j++){
s1[i][j] += m;
if(s[j] == 'A' + i){
cL[i][j + 1] = cL[i][j] + m; m++;
}else{
cL[i][j + 1] = cL[i][j];
}
}
cR[i][n] = 0; m = 0;
for(int j = n - 1; j >= 0; j--){
s1[i][j] -= m;
if(s[j] == 'A' + i){
cR[i][j] = cR[i][j + 1] + m; m++;
}else{
cR[i][j] = cR[i][j + 1];
}
}
}
dp[0] = 0; fill(dp + 1, dp + (1 << G), 1LL << 60);
for(int mask = 1; mask < (1 << G); mask++){
for(int j = 0; j < G; j++){
if(mask & (1 << j)){
int cost = min(f(mask, j, 0), f(mask, j, n));
int lo = 0, hi = n;
while(lo + 1 < hi){
int mid = (lo + hi) / 2;
int c = g(mask, j, mid);
if(c < 0) lo = mid;
else hi = mid;
}
for(int x = lo; x <= hi; x++){
int c = f(mask, j, x);
cost = min(cost, c);
}
dp[mask] = min(dp[mask], dp[mask - (1 << j)] + cost);
}
}
}
cout << setprecision(10) << fixed << ((long double) dp[(1 << G) - 1] / 2) << endl;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |