Educational Codeforces Round 31 F. Anti-Palindromize

本文介绍了一个算法问题:如何通过排列一个给定的字符串形成一个反回文串,同时使得串中相同字符位置的魅力值之和最大化。文章详细解释了问题背景、求解思路与步骤,并附带了一段C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值