CodeForces - 884F :Anti-Palindromize(贪心&费用流)
A string a of length m is called antipalindromic iff m is even, and for each i (1 ≤ i ≤ m) ai ≠ am - i + 1.
Ivan has a string s consisting of n lowercase Latin letters; n is even. He wants to form some string t that will be an antipalindromic permutation of s. Also Ivan has denoted the beauty of index i as bi, and the beauty of t as the sum of bi among all indices i such that si = ti.
Help Ivan to determine maximum possible beauty of t he can get.
Input
The first line contains one integer n (2 ≤ n ≤ 100, n is even) — the number of characters in s.
The second line contains the string s itself. It consists of only lowercase Latin letters, and it is guaranteed that its letters can be reordered to form an antipalindromic string.
The third line contains n integer numbers b1, b2, ..., bn (1 ≤ bi ≤ 100), where bi is the beauty of index i.
Output
Print one number — the maximum possible beauty of t.
Examples
8
abacabac
1 1 1 1 1 1 1 1
8
8
abaccaba
1 2 3 4 5 6 7 8
26
8
abacabca
1 2 3 4 4 3 2 1
17
题意:给定长长度为N的字符串,现在求一个重排列,使得对称位置不相同。如果重排后i位置的字母和原来相同,就得到对应位置的得分,求最大得分。
保证N是偶数,保证有满足条件的重排。
思路:最大费用最大流。
建图:
S-->26个字母:(字母个数,0);
字母-->N/2个位置:(1,val);val尽可能大就行,三种情况讨论。
N/2个位置-->T:(2,0)
#include<bits/stdc++.h> using namespace std; const int maxn=100000; const int inf=1<<30;int To[maxn],Laxt[maxn],Next[maxn],cap[maxn],cost[maxn]; int S,T,cnt=1,dis[maxn],ans; bool inq[maxn],vis[maxn]; deque<int>q; void add(int u,int v,int c,int cc) { Next[++cnt]=Laxt[u];Laxt[u]=cnt; To[cnt]=v;cap[cnt]=c;cost[cnt]=-cc; Next[++cnt]=Laxt[v];Laxt[v]=cnt; To[cnt]=u;cap[cnt]=0;cost[cnt]=cc; } bool spfa() { for(int i=0;i<=T;i++) inq[i]=0; for(int i=0;i<=T;i++) dis[i]=inf; inq[T]=1; dis[T]=0; q.push_back(T); while(!q.empty()) { int u=q.front(); q.pop_front(); inq[u]=0; for(int i=Laxt[u];i;i=Next[i]) { int v=To[i]; if(cap[i^1]&&dis[v]>dis[u]-cost[i]) { dis[v]=dis[u]-cost[i]; if(!inq[u]){ inq[v]=1; if(q.empty()||dis[v]>dis[q.front()]) q.push_back(v); else q.push_front(v); } } } } return dis[S]<inf; } int dfs(int u,int flow) { vis[u]=1; if(u==T||flow==0) return flow; int tmp,delta=0; for(int i=Laxt[u];i;i=Next[i]) { int v=To[i]; if((!vis[v])&&cap[i]&&dis[v]==dis[u]-cost[i]) { tmp=dfs(v,min(cap[i],flow-delta)); delta+=tmp; cap[i]-=tmp; cap[i^1]+=tmp; } } return delta; } char c[maxn]; int v[maxn],num[maxn]; int main() { int N,i,j; scanf("%d",&N); scanf("%s",c+1); for(i=1;i<=N;i++) scanf("%d",&v[i]),num[c[i]-'a'+1]++; S=0; T=26+N/2+1; for(i=1;i<=26;i++) add(S,i,num[i],0); for(i=1;i<=26;i++) for(j=1;j<=N/2;j++){ if(c[j]-'a'+1==i&&c[N+1-j]-'a'+1==i) add(i,j+26,1,max(v[j],v[N+1-j])); else if(c[j]-'a'+1==i) add(i,j+26,1,v[j]); else if(c[N+1-j]-'a'+1==i) add(i,j+26,1,v[N+1-j]); else add(i,j+26,1,0); } for(i=1;i<=N/2;i++) add(i+26,T,2,0); while(spfa()){ vis[T]=1; while(vis[T]){ for(i=0;i<=T;i++) vis[i]=0; ans-=dis[S]*dfs(S,N); } } printf("%d\n",ans); return 0; }