CodeForces-748D 贪心
这题的思维难度不是很大,属于编程实现细节处理较多的题。
暂且把每个字符串的“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; }
如有不当之处欢迎指出!
CodeForces-748D 贪心的更多相关文章
- CodeForces - 748D Santa Claus and a Palindrome (贪心+构造)
题意:给定k个长度为n的字符串,每个字符串有一个魅力值ai,在k个字符串中选取字符串组成回文串,使得组成的回文串魅力值最大. 分析: 1.若某字符串不是回文串a,但有与之对称的串b,将串a和串b所有的 ...
- CodeForces - 893D 贪心
http://codeforces.com/problemset/problem/893/D 题意 Recenlty Luba有一张信用卡可用,一开始金额为0,每天早上可以去充任意数量的钱.到了晚上, ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划
There are n people and k keys on a straight line. Every person wants to get to the office which is l ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 828D) - 贪心
Arkady needs your help again! This time he decided to build his own high-speed Internet exchange poi ...
- CodeForces - 93B(贪心+vector<pair<int,double> >+double 的精度操作
题目链接:http://codeforces.com/problemset/problem/93/B B. End of Exams time limit per test 1 second memo ...
- C - Ordering Pizza CodeForces - 867C 贪心 经典
C - Ordering Pizza CodeForces - 867C C - Ordering Pizza 这个是最难的,一个贪心,很经典,但是我不会,早训结束看了题解才知道怎么贪心的. 这个是先 ...
- Codeforces 570C 贪心
题目:http://codeforces.com/contest/570/problem/C 题意:给你一个字符串,由‘.’和小写字母组成.把两个相邻的‘.’替换成一个‘.’,算一次变换.现在给你一些 ...
- Codeforces 732e [贪心][stl乱搞]
/* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给n个插座,m个电脑.每个插座都有一个电压,每个电脑都有需求电压. 每个插座可以接若干变压器,每个变压器可以使得电压变为x/2上取整. 有无限个变 ...
- Codeforces 721D [贪心]
/* 不要低头,不要放弃,不要气馁,不要慌张. 题意: 给一列数a,可以进行k次操作,每次操作可以选取任意一个数加x或者减x,x是固定的数.求如何才能使得这个数列所有数乘积最小. 思路: 贪心...讨 ...
- CodeForces - 424B (贪心算法)
Megacity Time Limit: 2000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submit Sta ...
随机推荐
- JS 中的事件设计
看懂此文,不再困惑于 JS 中的事件设计 原文出处: aitangyong 抽空学习了下javascript和jquery的事件设计,收获颇大,总结此贴,和大家分享. (一)事件绑定的几种方式 ...
- Python输出hello world(各行命令详解)
创建main.py文件并粘贴下面代码 点击右键运行Debug 'main'后,下方的Debug窗口会出现ImportError: No module named 'bottle'这样的提示,提示导入b ...
- spring boot热部署
1.pom配置 参考:http://412887952-qq-com.iteye.com/blog/2300313 2.intellij配置 参考:http://blog.csdn.net/wjc47 ...
- 反向代理和HTTP重定向
1.什么是正向代理(前向代理)? 在NAT技术(Network Address Translation)出现之前,所有主机无法直接与外网相连,要想上网,需要连接到一台能够访问外网的Web服务器,再通过 ...
- canvas-海底气泡(面向对象编程)
需求:自动生成若干气泡,从海底往上浮: 1.基本的HTML结构: <!DOCTYPE html> <html> <head lang="en"> ...
- BZOJ 2115: [Wc2011] Xor [高斯消元XOR 线性基 图]
啦啦啦 题意: N 个点M条边的边带权的无向图,求1到n一条XOR和最大的路径 感觉把学的东西都用上了.... 1到n的所有路径可以由一条1到n的简单路径异或上任意个简单环得到 证明: 如果环与路径有 ...
- [Manacher]【学习笔记】
终于填坑啦......马拉车 课件上说的好短,但是明白了,讲解稍微修改一下抄上行了,比扩展KMP好写多了 求以每个字符为中心的最长回文串的半径.如果要求可以以字符间隙为回文中心,就要在每两个字符之间及 ...
- SDN第三次上机作业
作业链接 1.创建以下拓扑(可采用任意方式) 2.利用OVS命令下发流表,实现VLAN功能 3.利用OVS命令查看流表 4.验证性测试 5.Wireshark抓包验证
- JDBC【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】
1.PreparedStatement对象 PreparedStatement对象继承Statement对象,它比Statement对象更强大,使用起来更简单 Statement对象编译SQL语句时, ...
- Windows下Nginx的配置及配置文件部分介绍
一.在官网下载 nginx的Windows版本,官网下载:http://nginx.org/download/ 选择你自己想要的版本下载,解压 nginx(例如nginx-1.6.3) 包到你的win ...