[CF752D]Santa Claus and a Palindrome(优先队列,贪心乱搞)

题目链接: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 }
原文地址:https://www.cnblogs.com/kirai/p/6248764.html