1. 程式人生 > >【Codeforces748D】Santa Claus and a Palindrome [STL]

【Codeforces748D】Santa Claus and a Palindrome [STL]

hid isp truct 中間 回文 tdi printf 我們 none

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

【Codeforces748D】Santa Claus and a Palindrome [STL]