HDU 6103Kirinriki
来源:互联网 发布:制作电子文档软件 编辑:程序博客网 时间:2024/06/05 17:53
【题目链接】
http://acm.hdu.edu.cn/showproblem.php?pid=6103
题目意思
给出一串字符串,从中选出两个不重叠的字符串,使得两个字符串的距离和 <= m 的最长字符串长度,A,B 串中的字符距离计算为 disA,B=∑i=0n−1|Ai−Bn−1−i|
解题思路
看到这题时一开始想用的dp做后来,后来实在是想不出来动态转移方程(太菜没办法)后来发现直接用尺取就可以做了。从左右两边不断往中间收缩(从中间往两边扩也可以)。具体过程:i代表一个字符串的头从右边向左边移动,每次移动j都会从左边到右不断计算是否大于m了,大于了就把最靠边的不断减去直到加上后面的小于m,这样走一边就会找到以i为头的最长字符串(以i为头,但满足的字符串不一定要从i开始)。最后因为怕奇偶串所以要反过来再走遍。
代码部分
#include<bits/stdc++.h>using namespace std;#define ll long longint m,l;char s[50005];int solve(){ int ans=0; for (int i=l; i>=1; i--) { int d=0,t=0,p=0; for (int j=0; j<=i/2-1; j++) { d+=abs(s[1+j]-s[i-j]); if (d>m) ///当总和大于m,减去靠边的加上里面的; { d-=abs(s[1+p]-s[i-p]); d-=abs(s[1+j]-s[i-j]); p++; t--; j--; } else { t++; ans=max(ans,t); } } } return ans;}int main(){ int t; scanf("%d",&t); while(t--) { int ans=0; scanf("%d",&m); scanf("%s",s+1); l=strlen(s+1); ans=max(ans,solve()); reverse(s+1,s+l+1); ///反过来再跑遍 ans=max(ans,solve()); printf("%d\n",ans); } return 0;}
阅读全文
1 0
- HDU 6103 Kirinriki
- HDU 6103 Kirinriki
- HDU 6103 Kirinriki
- HDU 6103 Kirinriki
- hdu 6103 -Kirinriki
- hdu 6103 Kirinriki
- HDU 6103 Kirinriki 【dp】
- hdu 6103 Kirinriki
- HDU 6103 Kirinriki
- Kirinriki(HDU 6103)
- HDU-6103 Kirinriki
- hdu 6103 Kirinriki
- HDU 6103Kirinriki
- hdu--6103--Kirinriki
- 【思维】hdu 6103 Kirinriki
- HDU 6103 Kirinriki
- HDU 6103-Kirinriki
- HDU 6103 Kirinriki
- 什么是Android开发?
- <meta property=og的使用
- CodeForces
- 浅谈分布式锁
- 2017中国旅游暨安防机器人大赛总结
- HDU 6103Kirinriki
- 电脑内存暴涨!!运行奇慢无比!!
- ThinkPad E550 连蓝牙鼠标logitech M557
- Go 方法 学习笔记
- HDU6085-Rikka with Candies
- HDU
- MySql基础一
- java IO的概念和分类
- MAven学习 — <dependencies> && <dependencyManagement>