【Codeforces752D】Santa Claus and a Palindrome [STL]

Santa Claus and a Palindrome

Time Limit: 20 Sec  Memory Limit: 512 MB

Description

  有k个串,串长都是n,每个串有一个ai的贡献。
  选出若干个串,若它们可以通过任意组合,形成一个回文串,则可以获得它们的贡献之和。
  求最大贡献。

Input

  第一行两个整数k,n。
  之后k行,每行分别是一个串si,与贡献ai。

Output

  一个整数表示答案。

Sample Input

  7 3
  abb 2
  aaa -3
  bba -1
  zyz -4
  abb 5
  aaa 7
  xyx 4

Sample Output

  12

HINT

  1 ≤ k, n ≤ 100000;  n·k  ≤ 100000;  -10000 ≤ ai ≤ 10000

Solution

  首先,我们先考虑选了偶数个串的情况。显然是每两个互相颠倒的串匹配,尽量选大的值。

  但是现在可能选奇数个串,就是考虑把一个回文串放在中间,显然有两种情况:

    1. 匹配完还剩若干串,在剩下的串单独选了个回文串,显然加上最大的贡献即可;

    2. 把之前某些回文串两两匹配的给拆开改成只选较大的那一个,因为只选一个串可能贡献更大,A > (A + B)

  具体实现我们可以用一个Map指向一个vector,vector存下价值Map[s]=id表示s这个串用第id个vector记录信息

Code

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cmath>
 8 #include<map>
 9 #include<vector>
10 using namespace std;
11 typedef long long s64;
12 
13 const int ONE = 100005;
14 const int MOD = 1e9 + 7;
15 const int Base = 10005;
16 
17 int k, n;
18 
19 int total = 0;
20 map <string, int> id;
21 vector <int> A[ONE];
22 
23 int Ans;
24 
25 char s[ONE];
26 struct power
27 {
28         string s;
29         int val;
30 }a[ONE];
31 bool cmp(const power &a, const power &b) {return a.val > b.val;}
32 
33 
34 int get()
35 {
36         int res=1,Q=1;  char c;
37         while( (c=getchar())<48 || c>57)
38         if(c=='-')Q=-1;
39         if(Q) res=c-48; 
40         while((c=getchar())>=48 && c<=57) 
41         res=res*10+c-48;
42         return res*Q; 
43 }
44 
45 int main()
46 {
47         k = get(); n = get();
48         for(int i = 1; i <= k; i++)
49             cin>>a[i].s, a[i].val = get();
50 
51         sort(a + 1, a + k + 1, cmp);
52 
53         int maxx = 0;
54         for(int i = 1; i <= k; i++)
55         {
56             for(int j = 0; j < n; j++)
57                 s[n - 1 - j] = a[i].s[j];
58 
59             int to = id[string(a[i].s)];
60 
61             if(to && A[to].size())
62             {
63                 if(A[to][0] - Base + a[i].val > 0)
64                 {
65                     if(to == id[string(s)]) maxx = max(maxx, max(a[i].val, A[to][0] - Base) - (A[to][0] - Base + a[i].val));
66                     Ans += A[to][0] - Base + a[i].val;
67                     A[to].erase(A[to].begin());
68                     continue;
69                 }
70             }
71 
72             to = id[string(s)];
73             if(!to) to = id[string(s)] = ++total;
74 
75             A[to].push_back(a[i].val + Base);
76         }
77 
78         int res = 0;
79         for(int i = 1; i <= k; i++)
80         {
81             int pd = 1;
82             for(int j = 0; j < n; j++)
83                 if(a[i].s[n - 1 - j] != a[i].s[j]) {pd = 0; break;}
84             if(pd == 0) continue;
85 
86             int to = id[a[i].s];
87             if(A[to].size() >= 1)
88                 res = max(res, A[to][0] - Base);
89         }
90 
91         printf("%d", max(Ans + res, Ans + maxx));
92 }
View Code

 

posted @ 2017-11-01 16:01  BearChild  阅读(196)  评论(0编辑  收藏  举报