大体题意:
给你n 个字符串的权值,要求每个字符串最多使用一次,使得组成一个长的回文串,使得权值最大,如果最大权值为负数,则输出0.
思路:
真的被这道题恶心到了。
做这个题就是细心,讨论好就可以了。
我们可以开一个map<string,vector<int> >mp; 来存取每个字符串的权值,因为相同字符串可以有多个权值,所以用vector存。
枚举当前字符串s 时,如果发现不是回文串,直接找 s 对应的回文串,两边同时取最大值,因为肯定是一左一右。
如果是的话,就比较麻烦了。
我们先把最大的两个 都是正数的情况不断取出来。
把一正一负的那种单独拿出来,因为这种 可以选一种,也可以选两种。
最后把单独拿出来的 在暴力一下, 每一项作为一项 还是不作为一项,取个最大值即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <unordered_map>
#define ps push_back
#define fi first
#define se second
#define mr make_pair
#define Siz(x) (int)x.size()
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int inf = 0x3f3f3f3f;
const double eps = 1e-10;
const double pi = acos(-1.0);
const int maxn = 1e5 + 10;
//char s[maxn];
map<string,vector<int> >mp;
map<string,vector<int> >::iterator it;
vector<pair<int,int> >ine;
string s;
int a[maxn];
bool vis[maxn];
int rev[maxn];
bool hui[maxn];
int n,k;
bool judge(string &ss){
int len = k+1>>1;
for (int i = 0; i < len; ++i){
if (ss[i] != ss[k-i-1]) return 0;
}
return 1;
}
int main(){
std::ios::sync_with_stdio(false);
cin >> n >> k;
int u;
for (int i = 0; i < n; ++i){
cin >> s >> u;
mp[s].ps(u);
}
LL ans = 0;
LL Max = -inf;
for (it = mp.begin(); it != mp.end(); ++it){
vector<int>& tmp = it->se;
sort(tmp.begin(),tmp.end());
string s = it->fi;
if (!judge(s)){
if (Siz(tmp) == 0) continue;
reverse(s.begin(),s.end());
if (!mp.count(s))continue;
vector<int>& tmp2 = mp[s];
if (Siz(tmp2) == 0)continue;
sort(tmp2.begin(),tmp2.end());
while (tmp.back() + tmp2.back() > 0){
ans += tmp.back() + tmp2.back();
tmp.pop_back();
tmp2.pop_back();
if (Siz(tmp) == 0 || Siz(tmp2) == 0)break;
}
}
else {
while(Siz(tmp) >= 2){
if (tmp.back() > 0 && tmp[Siz(tmp) - 2] > 0){
ans += tmp.back() + tmp[Siz(tmp) - 2];
tmp.pop_back();
tmp.pop_back();
}
else {
if (tmp.back() > 0){
if (tmp.back() + tmp[Siz(tmp)-2] > 0){
ine.ps(mr(tmp.back(),tmp[Siz(tmp)-2]));
break;
}
else {
if (tmp.back() > Max)Max = tmp.back();
}
}
break;
}
}
if (Siz(tmp) == 1){
if (tmp.back() > 0){
if (Max < tmp.back())Max = tmp.back();
}
}
}
}
int pos= -1;
if (Max == -inf) Max = 0;
LL sum2 = 0;
for (int i = 0; i < Siz(ine); ++i){
sum2 += ine[i].fi+ine[i].se;
}
LL yuanlai = ans;
ans = -inf;
ans = max(ans,sum2 + Max);
for (int i = 0; i < Siz(ine); ++i){
ans = max(ans,sum2-ine[i].se);
}
cout << ans + yuanlai<<endl;
return 0;
}
/**
5 2
5
3
4
2
10
**/