F. Anti-Palindromize
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
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
input
8
abacabac
1 1 1 1 1 1 1 1
output
8
input
8
abaccaba
1 2 3 4 5 6 7 8
output
26
input
8
abacabca
1 2 3 4 4 3 2 1
output
17
题意:如果一个字符串长度n是偶数,并且s[i]!=s[n+1-i],那么这个串是反回文串,先在有一个串s,每一位有一个权值,要求用构造一个s串的排列t,t是反回文串,现在有一个魅力值,如果s[i]==t[i],那么魅力值加上这一位的权值,问魅力值最大多少,
做法:建一个反回文串并且尽量和原串尽量相同,先将每一位分类,第一类:s[i]==s[n+1-i],第二类s[i]!=s[n+1-i];对于第二类,它与它对应的点肯定至多只会有一个可以放,那么把第一类点相对应的较小的权值拿出来,然后把这些点放到其他位置,那么先放空着的点,如果全部放完了,计算s[i]==t[i]的权值,输出,如果还有剩余,可以证明剩下的点肯定是同一种类型,然后从第二类点中不存在等于剩下的那种店的数对中拿出较小的,然后把剩下的点与权值最小的那些交换位置。然后计算输出。
#include<bits/stdc++.h>
using namespace std;
int num[105];
int n;
char st[105];
int cnt[30];
int main(){
cin >> n;
scanf("%s",st+1);
for(int i = 1;i <= n;i ++) scanf("%d",&num[i]);
for(int i = 1;i <= n;i ++){
cnt[st[i]-'a']++;
}
int cns = 0;
int mx = 0;
for(int i = 0;i < 26;i ++) mx = max(mx,cnt[i]);
if(mx > n/2){
puts("0");
return 0;
}
mx = 0;
memset(cnt,0,sizeof(cnt));
for(int i = 1;i <= n/2;i ++) if(st[i] == st[n+1-i]) cnt[st[i]-'a'] ++,cns ++;
for(int i = 0;i <= 26;i ++) if(cnt[i] > cnt[mx]) mx = i;
int res = -1;
vector<int> v;
if(cnt[mx] > cns/2){
res = 2*cnt[mx] - cns;
}
else res = 0;
int ans = 0;
for(int i = 1;i <= n/2;i ++){
if(st[i] == st[n+1-i]) ans += max(num[i],num[n+1-i]);
else ans += num[i]+num[n+1-i];
}
if(res){
for(int i = 1;i <= n/2;i ++){
if(st[i] != st[n+1-i]){
if(st[i] == mx+'a' || st[n+1-i] == mx+'a'){
continue;
}
v.push_back(min(num[i],num[n+1-i]));
}
}
sort(v.begin(),v.end());
for(int i = 0;i < res;i ++){
ans -= v[i];
}
}
cout << ans << endl;
return 0;
}