【Codeforces748D】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 }

时间: 2024-08-07 00:47:51

【Codeforces748D】Santa Claus and a Palindrome [STL]的相关文章

CodeForces - 748D Santa Claus and a Palindrome (贪心+构造)

题意:给定k个长度为n的字符串,每个字符串有一个魅力值ai,在k个字符串中选取字符串组成回文串,使得组成的回文串魅力值最大. 分析: 1.若某字符串不是回文串a,但有与之对称的串b,将串a和串b所有的魅力值分别从大到小排序后,若两者之和大于0,则可以放在回文串的两边. 2.若某字符串是回文串,将其魅力值从大到小排序后,两两依次分析:(mid---可能放在回文串中间的串的最大魅力值) (1)若两个数都是正的,那么就将其放在两边,并将结果计入ans.(ans---回文串两边的串的魅力值之和) (2)

cf 478D.Santa Claus and a Palindrome

原来set,priority_queue也可以映射..涨姿势2333 比较麻烦的应该就是判断自身回文的串是选2个还是选一个吧. 1 #include<bits/stdc++.h> 2 #define INF 0x7fffffff 3 #define LL long long 4 #define N 100005 5 #define pill pair<int ,int > 6 using namespace std; 7 inline int ra() 8 { 9 int x=0,

【UVA】12504 Updating a Dictionary(STL)

题目 题目 ? ? 分析 第一次用stringstream,真TMD的好用 ? ? 代码 #include <bits/stdc++.h> using namespace std; int main() { int n; cin>>n; getchar();//回车 while(n--) { string s1,s2; getline(cin,s1); getline(cin,s2); for(int i=0;i<s1.length();i++) if(!isalpha(s1

【LeetCode】Palindrome Partitioning II 解题报告

[题目] Given a string s, partition s such that every substring of the partition is a palindrome. Return the minimum cuts needed for a palindrome partitioning of s. For example, given s = "aab", Return 1 since the palindrome partitioning ["aa&

【LeetCode】Palindrome Partitioning 解题报告

[题目] Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. For example, given s = "aab", Return [ ["aa","b"], ["a","a",

125. Valid Palindrome【easy】

125. Valid Palindrome[easy] Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. For example,"A man, a plan, a canal: Panama" is a palindrome."race a car" is not a palindrome. No

POJ1159 Palindrome 【动态规划】

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 52571   Accepted: 18124 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a

680. Valid Palindrome II【easy】

680. Valid Palindrome II[easy] Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome. Example 1: Input: "aba" Output: True Example 2: Input: "abca" Output: True Explanation: You co

【CF932G】Palindrome Partition 回文自动机

[CF932G]Palindrome Partition 题意:给你一个字符串s,问你有多少种方式,可以将s分割成k个子串,设k个子串是$x_1x_2...x_k$,满足$x_1=x_k,x_2=x_{k-1}...x_i=x{k-i+1}$. $|s|\le 10^6$ 题解:设字符串的长度为n,考虑字符串$T=s_1s_ns_2s_{n-1}...$.问题就转化成了:求将原串划分成若干个长度为偶数的回文子串的方案数. 首先我们有一种暴力的想法,设f[i]表示将前i个字符分成若干个回文子串的方