func_code_string: #include <bits/stdc++.h>   using namespace std;   const long long INF = numeric_limits<long long>::max() / 4;   struct MinCostMaxFlow {     int N;     vector<vector<long long> > cap, flow, cost;     vector<int> found;     vector<long long> dist, pi, width;     vector<pair<int, int> > dad;     MinCostMaxFlow(int N)         : N(N),           cap(N, vector<long long>(N)),           flow(N, vector<long long>(N)),           cost(N, vector<long long>(N)),           found(N),           dist(N),           pi(N),           width(N),           dad(N) {}     void AddEdge(int from, int to, long long cap, long long cost) {       this->cap[from][to] = cap;       this->cost[from][to] = cost;     }     void Relax(int s, int k, long long cap, long long cost, int dir) {       long long val = dist[s] + pi[s] - pi[k] + cost;       if (cap && val < dist[k]) {         dist[k] = val;         dad[k] = make_pair(s, dir);         width[k] = min(cap, width[s]);       }     }     long long Dijkstra(int s, int t) {       fill(found.begin(), found.end(), false);       fill(dist.begin(), dist.end(), INF);       fill(width.begin(), width.end(), 0);       dist[s] = 0;       width[s] = INF;       while (s != -1) {         int best = -1;         found[s] = true;         for (int k = 0; k < N; k++) {           if (found[k]) continue;           Relax(s, k, cap[s][k] - flow[s][k], cost[s][k], 1);           Relax(s, k, flow[k][s], -cost[k][s], -1);           if (best == -1 || dist[k] < dist[best]) best = k;         }         s = best;       }       for (int k = 0; k < N; k++) pi[k] = min(pi[k] + dist[k], INF);       return width[t];     }     pair<long long, long long> GetMaxFlow(int s, int t) {       long long totflow = 0, totcost = 0;       while (long long amt = Dijkstra(s, t)) {         totflow += amt;         for (int x = t; x != s; x = dad[x].first) {           if (dad[x].second == 1) {             flow[dad[x].first][x] += amt;             totcost += amt * cost[dad[x].first][x];           } else {             flow[x][dad[x].first] -= amt;             totcost -= amt * cost[x][dad[x].first];           }         }       }       return make_pair(totflow, totcost);     }   };   const int N = 105;   char s[N];   int b[N];   int main() {     int n;     cin >> n;     scanf( %s , s + 1);     int sum = 0;     int cnt[26];     for (int i = 0; i < 26; i++) cnt[i] = 0;     for (int i = 1; i <= n; i++) {       scanf( %d , b + i);       sum += b[i];       cnt[s[i] -  a ]++;     }     MinCostMaxFlow mcmf(1 + 26 + n / 2 + 1 + 1);     for (int i = 1; i <= 26; i++) {       mcmf.AddEdge(1, i + 1, cnt[i - 1], 0);     }     for (int i = 1; i <= n / 2; i++) {       mcmf.AddEdge(27 + i, 1 + 26 + n / 2 + 1, 2, 0);     }     for (int i = 1; i <= n / 2; i++) {       for (int j = 0; j < 26; j++) {         char k =  a  + j;         if (s[i] == k && s[n - i + 1] == k) {           mcmf.AddEdge(2 + j, 27 + i, 1, sum - max(b[i], b[n - i + 1]));         } else if (s[i] == k) {           mcmf.AddEdge(2 + j, 27 + i, 1, sum - b[i]);         } else if (s[n - i + 1] == k) {           mcmf.AddEdge(2 + j, 27 + i, 1, sum - b[n - i + 1]);         } else {           mcmf.AddEdge(2 + j, 27 + i, 1, sum);         }       }     }     auto e = mcmf.GetMaxFlow(1, 1 + 26 + n / 2 + 1);     cout << n * sum - e.second << endl;   }   