题目链接:http://codeforces.com/contest/752/problem/D
题意:给长度为k的n个字符串,每一个字符串有权值,求构造一个大回文串。使得权值最大。
因为字符串长度都一样,所以想构成回文串,必须两两配对,在中间加或者不加一个本身就是回文的字符串。
1.考虑非回文串的配对,把所有可以构成回文的非回文串凑起来,必须两两权值和>0才有意义。那么就扔到优先队列里配对。
2.考虑回文串的配对,配对成功的话要看下是不是两个回文串都是>0,如果不是,要额外在一个vector里记下,方便后面用。
3.这时候挑一个>0的,备选放在中间。
比较上面的2.3,求最优。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 typedef pair<LL, LL> pll; 6 const int maxn = 100100; 7 int n, k, tmp; 8 char s[maxn]; 9 vector<string> str, rev; 10 map<string, priority_queue<LL> > wt; 11 12 int main() { 13 // freopen("in", "r", stdin); 14 while(~scanf("%d%d",&n, &k)) { 15 wt.clear(); str.clear(); rev.clear(); 16 for(int i = 0; i < n; i++) { 17 scanf("%s %d", s, &tmp); 18 str.push_back(s); 19 rev.push_back(s); 20 reverse(rev[i].begin(), rev[i].end()); 21 wt[s].push(tmp); 22 } 23 LL ret = 0; 24 for(int i = 0; i < str.size(); i++) { 25 if(str[i] != rev[i]) { 26 while(wt[str[i]].size() > 0 && wt[rev[i]].size() > 0) { 27 int x = wt[str[i]].top(); 28 wt[str[i]].pop(); 29 int y = wt[rev[i]].top(); 30 wt[rev[i]].pop(); 31 if(x + y > 0) ret += x + y; 32 else { 33 if(x > 0) wt[str[i]].push(x); 34 if(y > 0) wt[rev[i]].push(y); 35 break; 36 } 37 } 38 } 39 } 40 vector<pll> tmp; 41 for(int i = 0; i < str.size(); i++) { 42 if(str[i] == rev[i]) { 43 while(wt[str[i]].size() > 1) { 44 int x = wt[str[i]].top(); 45 wt[str[i]].pop(); 46 int y = wt[str[i]].top(); 47 wt[str[i]].pop(); 48 if(x + y > 0) { 49 ret += x + y; 50 if(x > 0 && y > 0) continue; 51 if(x > y) swap(x, y); 52 tmp.push_back(pll(x, y)); 53 } 54 else { 55 if(x > 0) wt[str[i]].push(x); 56 if(y > 0) wt[str[i]].push(y); 57 break; 58 } 59 } 60 } 61 } 62 LL aa = maxn, bb; 63 for(int i = 0; i < tmp.size(); i++) { 64 if(tmp[i].first < aa) { 65 aa = tmp[i].first; 66 bb = tmp[i].second; 67 } 68 // cout << tmp[i].first << " " << tmp[i].second << endl; 69 } 70 LL qq = 0; 71 for(int i = 0; i < str.size(); i++) { 72 if(str[i] == rev[i]) { 73 if(wt[str[i]].size() > 0) { 74 if(wt[str[i]].top() > 0) { 75 qq = max(qq, wt[str[i]].top()); 76 } 77 } 78 } 79 } 80 if(aa == maxn) cout << max(ret + qq, ret) << endl; 81 else cout << max(max(ret, ret + qq), ret - LL(aa)) << endl; 82 } 83 return 0; 84 }