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

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<map>
#include<vector>
using namespace std;
typedef long long s64; const int ONE = ;
const int MOD = 1e9 + ;
const int Base = ; int k, n; int total = ;
map <string, int> id;
vector <int> A[ONE]; int Ans; char s[ONE];
struct power
{
string s;
int val;
}a[ONE];
bool cmp(const power &a, const power &b) {return a.val > b.val;} int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int main()
{
k = get(); n = get();
for(int i = ; i <= k; i++)
cin>>a[i].s, a[i].val = get(); sort(a + , a + k + , cmp); int maxx = ;
for(int i = ; i <= k; i++)
{
for(int j = ; j < n; j++)
s[n - - j] = a[i].s[j]; int to = id[string(a[i].s)]; if(to && A[to].size())
{
if(A[to][] - Base + a[i].val > )
{
if(to == id[string(s)]) maxx = max(maxx, max(a[i].val, A[to][] - Base) - (A[to][] - Base + a[i].val));
Ans += A[to][] - Base + a[i].val;
A[to].erase(A[to].begin());
continue;
}
} to = id[string(s)];
if(!to) to = id[string(s)] = ++total; A[to].push_back(a[i].val + Base);
} int res = ;
for(int i = ; i <= k; i++)
{
int pd = ;
for(int j = ; j < n; j++)
if(a[i].s[n - - j] != a[i].s[j]) {pd = ; break;}
if(pd == ) continue; int to = id[a[i].s];
if(A[to].size() >= )
res = max(res, A[to][] - Base);
} printf("%d", max(Ans + res, Ans + maxx));
}

【Codeforces752D】Santa Claus and a Palindrome [STL]的更多相关文章

  1. Codeforces Round #389 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 3) D. Santa Claus and a Palindrome STL

    D. Santa Claus and a Palindrome time limit per test 2 seconds memory limit per test 256 megabytes in ...

  2. Santa Claus and a Palindrome

    Santa Claus and a Palindrome 题目链接:http://codeforces.com/contest/752/problem/D 贪心 很自然地,可以想到,若subS不是回文 ...

  3. Codeforces Round #389 Div.2 D. Santa Claus and a Palindrome

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  4. 【BZOJ4099】Trapped in the Haybales Gold STL

    [BZOJ4099]Trapped in the Haybales Gold Description Farmer John has received a shipment of N large ha ...

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

    题目链接:http://codeforces.com/contest/752/problem/D 题意:给长度为k的n个字符串,每一个字符串有权值,求构造一个大回文串.使得权值最大. 因为字符串长度都 ...

  6. 【CF】7 Beta Round D. Palindrome Degree

    manacher+dp.其实理解manacher就可以解了,大水题,dp就是dp[i]=dp[i>>1]+1如何满足k-palindrome条件. /* 7D */ #include &l ...

  7. Codeforces 748D Santa Claus and a Palindrome

    雅礼集训期间我好像考完试就开始划水了啊 给出k个长度相同的字符串,每个串有一个权值,选出一些串连成一个回文串.使得选中的串的总权值最大. 如果选一个串,必须同时选一个对称的串.还有一个特殊情况是可以在 ...

  8. 【leetcode】564. Find the Closest Palindrome

    题目如下: 解题思路:既然是要求回文字符串,那么最终的输出结果就是对称的.要变成对称字符串,只要把处于对称位置上对应的两个字符中较大的那个变成较小的那个即可,假设n=1234,1和4对称所以把4变成1 ...

  9. cf 478D.Santa Claus and a Palindrome

    原来set,priority_queue也可以映射..涨姿势2333 比较麻烦的应该就是判断自身回文的串是选2个还是选一个吧. #include<bits/stdc++.h> #defin ...

随机推荐

  1. linux桌面使用鼠标中间健粘帖

    使用linux桌面很久了,一直习惯鼠标左键选中,右健弹出菜单复制粘帖. 没想到linux使用鼠标中间健粘帖,很方便. 参考:Linux鼠标中键复制粘贴之谜[Felix蛋疼科普贴] 用鼠标左键单击待复制 ...

  2. jQuery之offset,position

    获取/设置标签的位置数据 * offset(): 相对页面左上角的坐标 * position(): 相对于父元素左上角的坐标. 需求: 1. 点击 btn1 打印 div1 相对于页面左上角的位置 打 ...

  3. 小程序 坐标算距离 (copy)

      var EARTH_RADIUS = 6378137.0;    //单位M    var PI = Math.PI;        function getRad(d){        retu ...

  4. phaser3 微信小游戏若干问题

    纯属个人兴趣, 如有兴趣可共同参与维护. git: https://gitee.com/redw1234567/phaser3_wx image的地方需要修改,代码贴上 var ImageFile = ...

  5. SQL中的declare用法

    平时写SQL查询.存储过程都是凭着感觉来,没有探究过SQL的具体语法,一直都是按c#那一套往SQL上模仿,前几天项目中碰到一个问题引起了我对declare定义变量的作用域的兴趣. 大家都知道c#中的局 ...

  6. 【.Net+数据库】sqlserver的四种分页方式

    第一种:ROW_NUMBER() OVER()方式 select * from (  select *, ROW_NUMBER() OVER(Order by ArtistId ) AS RowId ...

  7. 一些noip模拟题一句话题解

    Problem A: 序列 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 12  Solved: 9[Submit][Status][Web Boar ...

  8. c++字符串排序

    在主函数中输入10个等长的字符串,用另一函数对它们排序.然后在主函数输出这10个已排好序的字符串. 用两种方法完成. 方法一:用二维数组做函数参数: 方法二:用指向一维数组的指针做函数参数. 方法一: ...

  9. 【Treeview】遍历本地磁盘

    一.前言 Treeview控件常用于遍历本地文件信息,通常与Datagridview与ImageList搭配.ImageList控件用于提供小图片给TreeView控件,DatagridView通常显 ...

  10. BZOJ4735 你的生命已如风中残烛 【数学】

    题目链接 BZOJ4735 题解 给定一个序列,有的位置为\(w_i - 1\),有的位置为\(-1\),问有多少种排列,使得任意前缀和非负? 我们末尾加上一个\(-1\),就是要保证除了末尾外的前缀 ...