Codeforces Round #389 (Div. 2):Santa Claus and a Palindrome

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

Santa Claus likes palindromes very much. There was his birthday recently. k of his friends came to him to congratulate him, and each of them presented to him a string si having the same length n. We denote the beauty of the i-th string by ai. It can happen that ai is negative — that means that Santa doesn't find this string beautiful at all.

Santa Claus is crazy about palindromes. He is thinking about the following question: what is the maximum possible total beauty of a palindrome which can be obtained by concatenating some (possibly all) of the strings he has? Each present can be used at most once. Note that all strings have the same length n.

Recall that a palindrome is a string that doesn't change after one reverses it.

Since the empty string is a palindrome too, the answer can't be negative. Even if all ai's are negative, Santa can obtain the empty string.

Input

The first line contains two positive integers k and n divided by space and denoting the number of Santa friends and the length of every string they've presented, respectively (1 ≤ k, n ≤ 100 000n·k  ≤ 100 000).

k lines follow. The i-th of them contains the string si and its beauty ai ( - 10 000 ≤ ai ≤ 10 000). The string consists of n lowercase English letters, and its beauty is integer. Some of strings may coincide. Also, equal strings can have different beauties.

Output

In the only line print the required maximum possible beauty.

Examples
input
7 3
abb 2
aaa -3
bba -1
zyz -4
abb 5
aaa 7
xyx 4
output
12
input
3 1
a 1
a 2
a 3
output
6
input
2 5
abcde 10000
abcde 10000
output
0

翻译:你有n个长度相等(可能相同)的字符串,每个字符串有一个价格(可以为负),你想用这n个字符串的其

中一部分组成一个回文串,求能组成的最贵字符串的价格

http://codeforces.com/contest/752/problem/D


思路:

用一个map<string, priority_queue<int> >来存字符串和它的价格,对于每个字符串有两种情况:

①自身不回文,②自身回文

对于①,我们需要一个对称串和它匹配,放在字符串的两边,只要这两个字符串的价格之和>0就选择(匹配方式:

每次都将当前最贵的本串和当前最贵的对称串进行匹配即可,注意pop)

对于②,可以和另一个一模一样的字符串一起放在字符串的两端,也可以单独一个作为整个回文串的最中间,这个

个贪心策略:只要此字符串当前队列顶端两个价格都为非负,那么就一定放在字符串的两端(还是注意pop),如

只有一个,那么考虑它是否也能和下一个价格为负的同串放在字符串的两端以增加总价格,如果不行,很显然只

能作为单串放中间(先不放,备用),如果可以就暂时放在字符串两端,最后判断是加一个单串好,是将一个配对

的串拆掉(负价格串扔掉,正价格串移到正中间),还是什么都不干好


#include<stdio.h>
#include<string>
#include<queue>
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
map<string, priority_queue<int> > p;
string jud[100005], temp;
int val;
int main(void)
{
	int n, k, i, now, x;
	long long ans;
	scanf("%d%d", &n, &k);
	for(i=1;i<=n;i++)
	{
		cin>>jud[i];
		scanf("%d", &val);
		p[jud[i]].push(val);
	}
	x = ans = 0;
	for(i=1;i<=n;i++)
	{
		temp = jud[i];
		reverse(temp.begin(), temp.end());
		if(temp!=jud[i])
		{
			while(p[temp].empty()==0 && p[jud[i]].empty()==0 && p[temp].top()+p[jud[i]].top()>0)		/*①*/
			{
				ans += p[temp].top()+p[jud[i]].top();
				p[temp].pop();
				p[jud[i]].pop();
			}
		}
		else		/*②*/
		{
			while(p[temp].size()>1)
			{
				now = p[temp].top();
				p[temp].pop();
				if(p[temp].top()+now>0)		/*放在队伍两端*/
				{
					ans += p[temp].top()+now;
					x = min(x, p[temp].top());
					p[temp].pop();
				}
				else
				{
					p[temp].push(now);
					break;
				}
			}
		}
	}
	x = -x;
	for(i=1;i<=n;i++)
	{
		temp = jud[i];
		reverse(temp.begin(), temp.end());
		if(temp==jud[i] && p[temp].empty()==0)
			x = max(x, p[temp].top());
	}
	printf("%I64d\n", ans+x); 
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值