CodeForces 748D Santa Claus and a Palindrome

  • 题目描述

    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.

    有k个长度为n的字符串,每个字符串有一个beauty度ai(可以为负数)。现将这些字符串连接组成一个回文字符串,新构成的回文字符串beauty度为构成该字符串的字串的beauty度之和。求所有新构成的回文字符串中最大的beauty度。(注意,空串的beauty度为0,所以最大beauty度不可能为负数。)

  • 输入

    样例输入#1:

    7 3
    abb 2
    aaa -3
    bba -1
    zyz -4
    abb 5
    aaa 7
    xyx 4
    

    样例输出#1:

    12
    

    样例输入#2:

    3 1
    a 1
    a 2
    a 3
    

    样例输出#2:

    6
    

    样例输入#3:

    2 5
    abcde 10000
    abcde 10000
    

    样例输出#3:

    0
    
  • 样例解释:

    In the first example Santa can obtain abbaaaxyxaaabba by concatenating strings 5, 2, 7, 6 and 3 (in this order).

  • 思路:

    1.若字符串是非回文字符串,那么它要找到它的反转字符串和它匹配,我们只要贪心地选取该字符串和它的反转字符串中beauty度最大的字符串,直到无法取得(自身或反转字符串已经被取完。

    2.若字符串是回文字符串,那么有两种可能:

    2-1.当该回文字符串只剩下一个,那么它只能插入字符串的中间。但是我们不知道是否取当前字符串是最优(可能还有其它只剩下一个的回文字符串,比当前回文字符串的beauty度大),所以我们需要保存当前字符串的beauty度rem。将rem和其他只剩下一个的字符串的beauty度比较,取有最大beauty度的字符串插入生成的字符串中间,即rem = max(rem,beauty[i]。

    2-2.当该回文字符串剩下大于等于二个时:

    取第一、第二大的两个串,他们的beauty度分别为a, b:

    1° 若a > 0 && b > 0:那么将这两个字符串插入两边是最优解。

    2° 若a + b < 0 && a > 0: 那么只能取a,是插入中间的情况,和2-1相同。

    3° 若a + b > 0 && b < 0:那么有两种情况:a,b都取并插入两边,或者只取a插入中间。(注意:最多只能有一个回文串插入生成的串的中间,所以如果取a插入中间那么rem就没法插入了。但是若取a,b插入两边,rem还是能插入中间的。所以这两种情况那种情况是更优情况我们现在还无法判断)。

    我们可以先将a, b插入两边,并记录b的值(b的值相当于比只插入a少掉的beauty值)。最后只要比较所有存储的b的值中的最小值sub(b是负数,相当于b的绝对值最大)和rem的值,若rem > |sub|(即 -|sub| + rem > 0)说明保留这个sub,加上rem的值是合算的(相当于取和sub所在的那一对回文字符串放在两边,再取rem放在中间会使生成串的beauty值增加),我们就将最后的答案加上rem;若rem < |sub|说明保留这个sub再加上rem值不合算(相当不应该配对然后中间放rem,而应将和sub配对的那个字符串放在中间),我们就将答案减去sub(相当于加上|sub|)。

    其余情况不管放在中间还是配对了放在两边都会使总beauty值减少,不符合题意。

    题目的关键在于2-2步,第一次做的时候错误的考虑了若a+b>0那么直接加入队伍,而没有考虑若b<0时,既可能a+b时最优解,也可能只取a放在中间是最优解。导致错误。

    本题的另一个难点在于构造数据结构。由于一个字符串和一个beauty值(int)对应,所以可以用map,并且我们每次要查看当前串的最大beauty值可以用优先队列。所以可以用map<string, priority_queue<int> >。

  • Answer:

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e5+7;
    int n;
    string revstr(string s){string ans = "";for(int i = 0; i < s.length(); i++){ans.insert(ans.begin(), s[i]);}return ans;
    }
    bool isrev(string s){for(int i = 0; i < n/2; i++){if(s[i] != s[n - i - 1])   return false;}return true;
    }
    struct s1{string str;int beauty;inline bool operator >(const s1& s2)const{return this->beauty > s2.beauty;}
    };
    map<string , priority_queue<int> > s;
    int main(void){int k, ans = 0;int rem = 0, sub = 0;cin >> k >> n;int cnt = 0;for(int i = 0; i < k; i++){string t;int b;cin >> t >> b;s[t].push(b);}for(map<string, priority_queue<int> >::iterator it = s.begin(); it != s.end(); ++it){string now = it -> first;string rev = revstr(now);while(!s[now].empty()){if(!isrev(now)){if(s.find(rev) != s.end() && !s[rev].empty()){int a = s[now].top(); s[now].pop();int b = s[rev].top(); s[rev].pop();if(a + b > 0){// cout << "now: " << now << " " << a << endl;// cout << "rev: " << rev << " " << b << endl;ans += (a+b);// cout << "ans: " << ans << endl;}}else{s[now].pop();}}else if(isrev(now)){int a = s[now].top();s[now].pop();if(!s[rev].empty()){int b = s[rev].top(); s[rev].pop();if(a > 0 && b >= 0){ans += (a+b);cnt += 2;}else if(a + b > 0 && b < 0){ans += (a+b);sub = min(sub, b);}else if(a + b <= 0 && a > 0){rem = max(rem, a);}else break;}else{if(a > 0){rem = max(rem, a);}else{break;}}}}}if(rem > -sub){ans += rem;}else    ans -= sub;cout << ans << endl;return 0;
    }
    

CodeForces 748D Santa Claus and a Palindrome相关推荐

  1. codeforces D Santa Claus and a Palindrome(hash+贪心)

    思路:计算字符串的正反哈希值.如果字符串不是回文串,并且存在字符串的反串,将这两上串作为构成回文串的两边.如果字符串是回文串,一种是将其作为回文串的中间,另外一种是作为回文串的对称串来处理. 具体代码 ...

  2. Santa Claus and a Palindrome

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

  3. 【codeforces 752C】Santa Claus and Robot

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. Codeforces Round #389 Div.2 C. Santa Claus and Robot

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

  5. 贪心+构造 Codeforces Round #277 (Div. 2) C. Palindrome Transformation

    题目传送门 1 /* 2 贪心+构造:因为是对称的,可以全都左一半考虑,过程很简单,但是能想到就很难了 3 */ 4 /**************************************** ...

  6. Dear Santa Claus圣诞老人创意字体 for mac

    Dear Santa Claus Font是一种甜美而友好的手写字体.看起来好像是孩子的笔迹,因此,此圣诞老人创意Mac字体将是写给圣诞老人的信或给您的作品增添些许纯真的完美选择.Mac圣诞老人创意字 ...

  7. UVA 291 The House Of Santa Claus(DFS/深搜)

    The House Of Santa Claus Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu ...

  8. CodeForces - 906E Reverses(回文自动机+Palindrome Series优化dp)

    题目链接:点击查看 题目大意:给出两个字符串 s 和 t,每次可以在字符串 s 中选择数个不相交的字串进行反转,问最少需要反转多少次,可以使得字符串 s 和 t 相等,输出最小反转次数以及方案 题目分 ...

  9. CodeForces - 17E Palisection(回文自动机/Palindrome Series优化dp)

    题目链接:点击查看 题目大意:给出一个长度为 n 的字符串,问有多少 相交的回文子串对数 题目分析:背 PAM 模板的时候突然发现了一道模板题,于是顺手写了..正难则反,可以先求出有多少个互不相交的回 ...

最新文章

  1. 端口号被占用怎么解决
  2. android 获取视频大小,Android 获取视频缩略图(获取视频每帧数据)的优化方案
  3. 新疆自考大专计算机应用专业,新疆大学2017年新疆自考计算机信息管理(专科)考试计划...
  4. Linux缺少qt5core,关于qt5:无法运行Qt应用:找不到版本“ Qt_5”
  5. c 编程 mysql结果集_使用mysql C语言API编写程序—MYSQL数据库查询操作(执行查询操作,获取查询结果的字段数,记录行数,...
  6. 华为畅享max有没有人脸识别_看到Meeting视频会议一体机融合华为分布式能力,共建智能会议新体验...
  7. scrapy使用pipeline保存不同的表单Item到数据库、本地文件
  8. 《精通软件性能测试与LoadRunner最佳实战》—第1章1.1节软件测试基础
  9. 操作系统—内存的连续分配管理方式
  10. 拉丁字母表及中英文发音
  11. [JL]最后的晚餐 动态规划(DP) codevs5318
  12. 转载 nat64 流程描述 通俗易懂
  13. latex参考文献bib基本格式_在Latex中利用.bib进行参考文献管理
  14. 计算机管理无guest用户,win10管理账户里头没有guest账户
  15. 树莓派更改python版本_为树莓派升级Python版本
  16. 现代OpenGL教程 02——贴图
  17. 一起刷 leetcode 之旋转矩阵(头条/华为/陌陌真题)
  18. oracle10r2的新特性
  19. DNF启动时出现“tcls Parsing Failed“ 的解决方法
  20. mysql数据库性能测试工具推荐

热门文章

  1. 如何成为人群中的亮点?能说会道是成功人士的共同品质
  2. 为什么朋友圈总有些环游世界的人? 可能大部分是...
  3. vm14安装mac os 10.14.5教程
  4. PS学习笔记——色彩基础和吸管工具
  5. 求一个3×3矩阵对角线元素之和
  6. pytorch中contiguous()
  7. 涅磐.人间.灵(师傅)
  8. react入门-点击变色
  9. 数学建模清风微信公众号的习题答案(基础篇-填空题)
  10. overflow属性