1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| #include < cstdio > #include < cstring > #include < algorithm > #include < queue > using namespace std; const int maxn=1000005; const int inf=0x7f7f7f7f; struct node { int to,next,cost,flow; } edge[maxn<<1]; int head[maxn],dist[10005],k=1,tot_cost=0,ans=0,s,t; bool visit[10005]; void add(int u,int v,int w,int c) { edge[++k].to=v;edge[k].next=head[u];edge[k].flow=w;edge[k].cost=c;head[u]=k; swap(u,v); edge[++k].to=v;edge[k].next=head[u];edge[k].flow=0;edge[k].cost=-c;head[u]=k; } bool spfa() { memset(dist,inf,sizeof(dist)); memset(visit,false,sizeof(visit)); dist[t]=0;visit[t]=true;deque<int> q;q.push_back(t); while(!q.empty()) { int x=q.front();q.pop_front();visit[x]=false; for(int i=head[x];i;i=edge[i].next) { if(dist[edge[i].to]>dist[x]-edge[i].cost&&edge[i^1].flow) { dist[edge[i].to]=dist[x]-edge[i].cost; if(!visit[edge[i].to]) { visit[edge[i].to]=true; if(!q.empty()&&dist[q.front()]>dist[edge[i].to]) q.push_front(edge[i].to); else q.push_back(edge[i].to); } } } } return dist[s]!=inf; } int dfs(int x,int f) { visit[x]=true; if(x==t||!f) return f; int flow=0; for(int i=head[x];i;i=edge[i].next) { if(visit[edge[i].to]) continue; if(dist[edge[i].to]!=dist[x]-edge[i].cost||!edge[i].flow) continue; int temp=dfs(edge[i].to,min(f-flow,edge[i].flow)); edge[i].flow-=temp; edge[i^1].flow+=temp; flow+=temp; tot_cost+=temp*edge[i].cost; if(f==flow) break; } return flow; } void zkw() { while(spfa()) { visit[t]=true; while(visit[t]) { memset(visit,false,sizeof(visit)); dfs(s,inf); } } } int cnt[maxn],n,b[maxn],alp[maxn]; char str[maxn]; int main() { #ifdef lemon freopen("844f.in","r",stdin); #endif scanf("%d",&n);s=0;t=4000; scanf("%s",str+1); for(int i=1;i<=n;i++) alp[i]=str[i]-'a'+1; for(int i=1;i<=n;i++) scanf("%d",&b[i]),ans+=b[i]; for(int i=1;i<=n;i++) cnt[alp[i]]++; for(int i=1;i<=26;i++) { add(s,i,cnt[i],0); for(int j=1;j<=(n>>1);j++) { add(i,100*i+j,1,0); if(alp[j]==i) add(100*i+j,3000+j,1,0); else add(100*i+j,3000+j,1,b[j]); if(alp[n-j+1]==i) add(100*i+j,3000+n-j+1,1,0); else add(100*i+j,3000+n-j+1,1,b[n-j+1]); } } for(int i=1;i<=n;i++) add(3000+i,t,1,0); zkw(); printf("%d",ans-tot_cost); return 0; }
|