#include <bits/stdc++.h>
using namespace std;
const int maxn = 10005, maxg = 15, off = 1024;
int n, g;
string s;
double prosli[maxn][maxg];
int red[maxg], red2[maxg], red3[maxg];
double ukp[maxg];
double lijevo[off][maxn], desno[off][maxn], dodaj[off][maxn];
vector <int> mjesta[maxg];
double ans = 1e18;
double dp[maxg][off];
double calc (int i, int x, int mask){
//cout << i << " " << x << " " << mask << " " << dp[i][mask] << endl;
if (abs(dp[i][mask] + 1) > 0.01) return dp[i][mask];
for (int j = 0; j < g; j++){
if (mask & (1 << j)){
int y = calc(j, red3[j], mask - (1 << j));
break;
}
}
double tr = 0;
for (int j = 0; j < mjesta[x].size(); j++){
int y = mjesta[x][j];
tr += min(lijevo[mask][y] + (prosli[y][x] - 1) / 2, desno[mask][y] + (ukp[x] - prosli[y][x]) / 2);
}
for (int j = 0; j < n; j++) dodaj[mask + (1 << i)][j] = dodaj[mask][j];
for (int j = 0; j < mjesta[x].size(); j++) dodaj[mask + (1 << i)][mjesta[x][j]] = 1;
for (int j = 0; j < n; j++){
if (j == 0) lijevo[mask + (1 << i)][j] = dodaj[mask + (1 << i)][j];
else lijevo[mask + (1 << i)][j] = lijevo[mask + (1 << i)][j - 1] + dodaj[mask + (1 << i)][j];
}
for (int j = n - 1; j >= 0; j--){
if (j == n - 1) desno[mask + (1 << i)][j] = dodaj[mask + (1 << i)][j];
else desno[mask + (1 << i)][j] = desno[mask + (1 << i)][j + 1] + dodaj[mask + (1 << i)][j];
}
//cout << i << " " << mask << " " << tr << endl;
//cout << lijevo[mask][0] << lijevo[mask][1] << lijevo[mask][2] << lijevo[mask][3] << lijevo[mask][4] << lijevo[mask][5] << endl;
//cout << desno[mask][0] << desno[mask][1] << desno[mask][2] << desno[mask][3] << desno[mask][4] << desno[mask][5] <<endl;
return dp[i][mask] = tr;
}
int main (void){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> s;
n = s.size();
memset(prosli, 0, sizeof prosli);
for (int i = 0; i < n; i++){
if (i != 0){
for (int j = 0; j < 15; j++) prosli[i][j] = prosli[i - 1][j];
}
int j = s[i] - 'A';
if (prosli[i][j] == 0) red2[g] = g, red[g] = j, red3[g] = j, g++;
prosli[i][j]++;
ukp[j]++;
mjesta[j].push_back(i);
}
sort(red, red + g);
sort(red3, red3 + g);
for (int i = 0; i < 10; i++){
for (int j = 0; j < 1024; j++) dp[i][j] = -1;
}
do{
double tr = 0;
int mask = 0;
for (int i = 0; i < g; i++){
tr += calc(red2[i], red[i], mask);
mask += (1 << red2[i]);
//cout << tr << "\n";
}
ans = min(ans, tr);
}while (next_permutation(red, red + g) and next_permutation(red2, red2 + g));
cout << fixed << setprecision(10);
cout << ans << "\n";
return 0;
}
# | 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... |