题意:给定k个长度为n的字符串,每个字符串有一个魅力值ai,在k个字符串中选取字符串组成回文串,使得组成的回文串魅力值最大。

分析:

1、若某字符串不是回文串a,但有与之对称的串b,将串a和串b所有的魅力值分别从大到小排序后,若两者之和大于0,则可以放在回文串的两边。

2、若某字符串是回文串,将其魅力值从大到小排序后,两两依次分析:(mid---可能放在回文串中间的串的最大魅力值)

(1)若两个数都是正的,那么就将其放在两边,并将结果计入ans。(ans---回文串两边的串的魅力值之和)

(2)若一正一负,且正数绝对值大,可以放在两边,也可以将正数放在中间同时舍去负数。

那么先假定这两个数是放在两边的,并将结果计入ans。

若该正数放在回文串的中间最终是mid的最大值,那么实际上结果增加了是负数的绝对值,所以将负数的绝对值与mid比较,并更新。

eg:

(i)aaa:5,-3;bbb:4;

aaa放在中间相对于放在两边最终的结果是增加了3,而bbb放在中间最终的结果是增加了4,所以aaa应当放在两边,而且中间的串应取bbb。

(ii)aaa:5,-3;bbb:2;

aaa放在中间相对于放在两边最终的结果是增加了3,而bbb放在中间最终的结果是增加了2,所以aaa放在中间是最好的情况,mid应取3。

(3)若一正一负,且负数绝对值大,那么一定不能放在两边(因为两者之和小于0),但正数可以放在中间,更新mid。

(4)若两数都是负的,那么不放进回文串。

#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
const double eps = 1e-8;
inline int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 100000 + 10;
const int MAXT = 1000000 + 10;
using namespace std;
map<string, int> mp;
vector<int> v[MAXN];
vector<string> t;
int k, n;
string s;
int cnt;
int vis[MAXN];
void init(){
cnt = 0;
for(int i = 0; i < MAXN; ++i) v[i].clear();
mp.clear();
memset(vis, 0, sizeof vis);
t.clear();
}
int get_id(string x){
if(mp.count(x)) return mp[x];
return mp[x] = ++cnt;
}
bool judge(string x){
for(int i = 0; i < n / 2; ++i)
if(x[i] != x[n - i - 1]) return false;
return true;
}
int main(){
while(scanf("%d%d", &k, &n) == 2){
init();
for(int i = 0; i < k; ++i){
cin >> s;
int id = get_id(s);
int value;
scanf("%d", &value);
v[id].push_back(value);
if(judge(s)) vis[id] = -1;//回文串
else{
t.push_back(s);//非回文串
}
}
int l = t.size();
for(int i = 0; i < l; ++i){
string tt = t[i];
reverse(t[i].begin(), t[i].end());
if(mp.count(t[i])){
vis[mp[tt]] = mp[t[i]];
}
}
int ans = 0;
int mid = 0;
for(int i = 1; i <= cnt; ++i){
if(!vis[i]) continue;
if(vis[i] != -1){//非回文串且有对称串
vis[vis[i]] = 0;
int tmp_id = vis[i];
int len = Min(v[i].size(), v[tmp_id].size());
sort(v[i].begin(), v[i].end(), greater<int>());
sort(v[tmp_id].begin(), v[tmp_id].end(), greater<int>());
for(int j = 0; j < len; ++j){
if(v[i][j] + v[tmp_id][j] > 0) ans += v[i][j] + v[tmp_id][j];
else break;
}
}
else{
int len = v[i].size();
if(len == 1){
mid = Max(mid, v[i][0]);
continue;
}
sort(v[i].begin(), v[i].end(), greater<int>());
for(int j = 0; j < len; j += 2){
if(j + 1 < len){
if(v[i][j] + v[i][j + 1] > 0){
ans += v[i][j] + v[i][j + 1];
if(v[i][j] >= 0 && v[i][j + 1] < 0){
mid = Max(mid, -v[i][j + 1]);
}
else if(v[i][j] < 0 && v[i][j + 1] >= 0){
mid = Max(mid, -v[i][j]);
}
}
else{
if(v[i][j] >= 0){
mid = Max(mid, v[i][j]);
}
else if(v[i][j + 1] >= 0){
mid = Max(mid, v[i][j + 1]);
}
else break;
}
}
else{
if(v[i][j] > 0) mid = Max(mid, v[i][j]);
}
}
}
}
printf("%d\n", ans + mid);
}
return 0;
}

  

CodeForces - 748D Santa Claus and a Palindrome (贪心+构造)的更多相关文章

  1. Codeforces 748D Santa Claus and a Palindrome

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

  2. 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 ...

  3. Santa Claus and a Palindrome

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

  4. 【Codeforces752D】Santa Claus and a Palindrome [STL]

    Santa Claus and a Palindrome Time Limit: 20 Sec  Memory Limit: 512 MB Description 有k个串,串长都是n,每个串有一个a ...

  5. 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 ...

  6. Codeforces 752C - Santa Claus and Robot - [简单思维题]

    题目链接:http://codeforces.com/problemset/problem/752/C time limit per test 2 seconds memory limit per t ...

  7. codeforces 748E Santa Claus and Tangerines

    E. Santa Claus and Tangerines time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  8. Codeforces 784B Santa Claus and Keyboard Check

    题面: 传送门 B. Santa Claus and Keyboard Check Input file: standard input Output file: standard output Time ...

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

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

随机推荐

  1. 51nod 1368:黑白棋 二分图最大匹配

    1368 黑白棋 题目来源: TopCoder 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题  收藏  取消关注 有一个N*M的棋盘(1<=N,M< ...

  2. IDEA自用插件,驼峰插件,MyBatis插件,Lombok插件

    IDEA自用插件 驼峰插件:CamelCase,Shift + Alt + u快速切换驼峰 MyBatisX插件:快速在mapper之间跳转 Lombok插件:注解实现get.set方法 MyBati ...

  3. 洛谷 P2375 [NOI2014]动物园

    题目传送门 解题思路: 其实对于一个sum[i],其值就等于sum[next[i]] + sum[next[next[i]]] + ... + 1,然后我们可以记忆化,然后题目里又有一个限制,就是前后 ...

  4. Java笔记--反射机制

    1.Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法. 2.Java反射机制提供 ...

  5. Redis集群环境之linux搭建多机版---已完结,跟着一步一步来你就可以集群成功

    上一篇踩着各种坑写了Redis集群环境之linux搭建单机版,这一篇准备就多机版集群进行搭建,主要目的一来是在上一篇的基础上进行精华提粹总结,二来是把单机版与多机版的区别进行记录. 首先软硬件环境: ...

  6. C++面试常见问题——02动态分配内存

    动态分配内存 C++动态内存 C++程序中内存分为两个部分 堆:程序中未使用的内存,在程序运行时可用于动态分配内存. 栈:函数内部申明的所有变量都将占用栈内存. 很多时候不知道一个程序到底需要多少内存 ...

  7. 获取指定进程号,并kill掉

    直接上案例: 例子:获取nginx进程 方法:$ps -aux |grep nginx |grep -v grep |awk '{print $2}'  或者 $ps -ef |grep nginx ...

  8. 161-PHP 文本替换函数str_replace(二)

    <?php $str='Hello world!'; //定义源字符串 $search='o'; //定义将被替换的字符 $replace='O'; //定义替换的字符串 $res=str_re ...

  9. T_SQL 将一列多行数据合并为一行

    SQL Server在进行数据迁移和报表处理的时候会遇到将一列多行数据拼接为一个字符串的情况,为了处理这个问题,在网上找了一些相关的资料,提供两种方法,供遇到类似问题的朋友们参考,也借此加深自己的印象 ...

  10. 关于Business Terminology,你需要了解的三件事

    严格意义上来说,商科论文形式的考核,主观因素会有很大的影响.这也是为什么雅思考试中,口语和写作的分数很少有出现满分的原因.除开硬性标准外(如行文逻辑,扣题准确度以及文献资料准确引用等),商科高分论文都 ...