这题的思维难度不是很大,属于编程实现细节处理较多的题。

暂且把每个字符串的“beauty”称为魅力值,用一个优先队列数组将同一个字符串的所有魅力值保存,通过map将不同字符串编号,就可以十分方便的查询到每个字符按串对应的魅力值队列了。之所以使用优先队列,是因为先处理魅力值更大的才能使得最后的回文串魅力值的和最大。

每个字符串氛围回文串和非回文串,应该分开考虑。

1.先处理非回文字符串,非回文字符串必须把它本身和它的对称串同时处理,因为两个才能对称嘛。

首先取两个字符串队首的魅力值:

int m=q[h].top(); q[h].pop();
int n=q[f].top(); q[f].pop();

对于m和n,当m<0,直接退出;

如果m+n<=0 直接退出;

如果m+n>0   加入最后的答案即可.

2.然后处理较为复杂的回文串。特别注意,回文串可以单独放置一个,因为它自身就是对称的。

1.如果回文串队列中只剩余1个字符串,即q[h].size()==1

如果小于等于0,直接退出;

如果大于零,不能直接退出,因为它可能最后被选中作为单独放置。当然,最后可能会出现多个可能单独放置的回文串,显而易见应该选择魅力值最大的回文串。因此直接用一个变量把最大值保存即可。

2.如果回文串队列中,剩余多个字符串时,取队首前两个元素:

int m=q[h].top(); q[h].pop();
int n=q[h].top(); q[h].pop();

如果m<=0,直接退出;

如果m>0&&n>=0,则将m+n加入最后答案;

如果m>0&&n<0,若m+n>0,此时m、n面临两种选择,要么直接选择m和n直接加入最后答案,或择将m作为单独放置。当然此时无法做出最佳选择,应该加入另外一个结构体数组中,结构体中存储两个元素m和n;若m+n<=0直接将m与此时最大单独放置的值进行比较,取较大值,之所以能直接作为单独放置的选择,是因为m+n<0对最后的答案没有帮助,如果只选择m可能会有帮助。

3.最后一步就是处理单独的放置最大值,以及结构体数组:

因为一定要选择一个单独放置的回文串,那么就枚举结构体数组,如果结构体数组中某个元素的m作为单独放置之后,其他元素一定会全部取m+n,因为要使得最后的魅力值之和最大,也可能是去原先单独放置的最大值,同时把结构体中所有元素都取m+n。

我想可能很多地方都没有讲清楚,大家对这题有什么问题欢迎提出。

AC代码:

#include<cstdio>
#include<map>
#include<queue>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
struct node{int a,b;node(){}node(int a,int b):a(a),b(b){    }
}w[maxn];
string str[maxn];
string rever(string p){string s="";for(int i=p.size()-1;i>=0;--i){s+=p[i];}return s;
}
bool is_pal(string p){int x=0,y=p.size()-1;while(x<y){if(p[x]!=p[y]) return false;x++;y--;}return true;
}
map<string,int>ha1,ha2;
priority_queue<int>q[maxn];
vector<node>pal;
int main(){int k,n;while(scanf("%d%d",&k,&n)!=EOF){int big=0; //最大选择string a;int b;int x=-1;for(int i=0;i<k;++i){cin>>a>>b;str[i]=a;int ind;if(!ha2.count(a)) {++x; ind=x;ha2[a]=x;}else ind=ha2[a];q[ind].push(b); }int ans=0;for(int i=0;i<k;++i){if(ha1[str[i]]==1) continue;ha1[str[i]]=ha1[rever(str[i])]=1;int h=ha2[str[i]];if(is_pal(str[i])){if(q[h].empty()||q[h].top()<=0) continue;while(!q[h].empty()&&q[h].top()>0){if(q[h].size()==1){if(q[h].top()>0) big=max(big,q[h].top());q[h].pop();}else {int m=q[h].top(); q[h].pop();int n=q[h].top(); q[h].pop();if(m>0){if(n<0) {if(m+n>0) pal.push_back(node(m,n));else big=max(big,m);}else if(n>=0) ans+=m+n;}}} }     else{if(q[h].empty()) continue;string s=rever(str[i]);if(!ha2.count(s)) continue; //找不到对称串 int f=ha2[s];while(!q[h].empty()&&!q[f].empty()){int m=q[h].top(); q[h].pop();int n=q[f].top(); q[f].pop();if(m+n<=0) break;else if(m+n>0) ans+=m+n;}}}int sum=0;for(int i=0;i<pal.size();++i){sum+=pal[i].a+pal[i].b;}int u=sum+big;for(int i=0;i<pal.size();++i){if(pal[i].a>big) u=max(u,sum-pal[i].b); }ans+=u;printf("%d\n",ans);}return 0;
} 

如有不当之处欢迎指出!

转载于:https://www.cnblogs.com/flyawayl/p/8305499.html

CodeForces-748D 贪心相关推荐

  1. CodeForces 748D Santa Claus and a Palindrome

    CodeForces 748D Santa Claus and a Palindrome 题目描述 Santa Claus likes palindromes very much. There was ...

  2. 贪心 ---- Codeforces Global Round 8,B. Codeforces Subsequences[贪心,贪的乘法原理]

    题目链接 给出字符串,统计子串(子串字母可以跳跃)是codeforces的数量. 本题要求,给出子串最少数量k,构造字符串s,要求字符串s包含的字母数量最少,输出这个最少的字符串s. 题目要求是至少有 ...

  3. CodeForces - 93B(贪心+vectorpairint,double +double 的精度操作

    题目链接:http://codeforces.com/problemset/problem/93/B B. End of Exams time limit per test 1 second memo ...

  4. Codeforces 985C (贪心)

    传送门 题面: C. Liebig's Barrels time limit per test 2 seconds memory limit per test 256 megabytes input ...

  5. Minimize the Permutation CodeForces - 1256(贪心)

    题意: q次询问,每次询问给你长度为n的排列,然后你每次可以选择一个位置i和i+1的数字进行交换.但是每个位置只能交换一次,问你反转若干次后,这个排列最小是多少? 题目: You are given ...

  6. Minimizing Difference CodeForces - 1244E(贪心题)

    题目 题意 官方题解: 百度翻译 思路 ac代码 题意 给出一列数,至多n个操作使其中的数+1或-1,要求得到最小的差值(最大值-最小值): You are given a sequence a1_{ ...

  7. Serval and Parenthesis Sequence CodeForces - 1153C 贪心

    题意:给出一个由"(",")","?"三种字符构成的序列,让我们把其中的问号替换成左右括号,使得整个序列变成一个完整地括号序列,也就是括号匹 ...

  8. CodeForces - 1089L 贪心

    The kingdom of Lazyland is the home to nn idlers. These idlers are incredibly lazy and create many p ...

  9. Too Many Segments (easy version) CodeForces - 1249D1(贪心+差分)

    题意 给多组线段,而每一个点的覆盖次数不超过K,每次可去除一个线段,问最少去多少线段以及线段的位置. The only difference between easy and hard version ...

  10. Codeforces 360E 贪心 最短路

    题意及思路:https://blog.csdn.net/huanghongxun/article/details/49846927 在假设所有边都是最大值的情况下,如果第一个人能比第二个人先到,那就缩 ...

最新文章

  1. 基于matlab的dsp调试方法,基于Matlab7.0的DSP调试
  2. 数据驱动才是零售企业转型的核心!
  3. DB2性能调节工作总结
  4. Python Django session存取值代码演示及jsonpickle序列化
  5. 软件测试—软件测试基础知识—测试用例设计的方法之等价类和边界值
  6. c语言广播程序,C语言socket编程---udp通信及广播
  7. 《BI那点儿事》Microsoft 决策树算法
  8. Window系统: 解决 win xp系统 最新版QQ/TIM安装包 报错误 安装包可能被非法改动导致安装失败 云云.2021-02-15
  9. 嵌入式——嵌入式与单片机傻傻分不清
  10. 英雄之盾-第11届蓝桥杯Scratch省赛真题第4题
  11. 内边距和外边距,清除默认的内外边距
  12. 【科学有故事】做节目时的Python分析
  13. 局域网内PC端远程监控android设备界面
  14. 与同行的对比,M-DAO的崛起已成定局
  15. Unity 项目游戏退出代码
  16. Python日历模块| 使用示例的weekday()方法
  17. JavaScript sort 方法 默认排序顺序为按字母升序-数组常用方法
  18. 申请企业邮箱购买步骤,外贸企业邮箱注册流程步骤
  19. 【文本生成】评价指标:BARTScore
  20. 8.windbg-vertarget、lm

热门文章

  1. 讲个故事为什么IP地址与Mac地址缺一不可?
  2. android 自定义View 的详细介绍
  3. HTML5 Canvas 画虚线组件
  4. 将不确定变为确定~真的是SqlDataReader引起的超时?
  5. 跨网段加域的一个问题
  6. Robots.txt 协议——百度之星
  7. HTML与XHTML区别
  8. c语言表达式10 3的结果是,C语言程序设计--第3讲运算符与表达式.ppt
  9. devops流程工具_您的DevOps工作流程依赖哪些工具?
  10. fameview搅拌机控件_搅拌机爱好者齐聚第十五届年会