前言

每次做出来什么本来做不出的题目,就忍不住记录一下。不过大多时候隔几天来看,就发现,啊,我当时只是做了一道这么弱智的题目呀,哈哈。前缀和确实不算太难。。

传送门

题目大意

给你一个字符串只含G和R,求一个最长子串长度,使得两个字符的长度相等。(给的字符串长小于1e6)

如:GRGGRG

答案是:4。

思路

题目中字符串很长,暴力枚举显然不可能。

但我们仔细一看,发现不过只有两个字符G和H。我们令G为1,令R为-1,那么GR的值就为0,这显然是一个可行的子串。

那再看GRGGRG,我们开一个a数组记录前i个字符的值,那么

a[0]=0,a[1]=1,a[2]=0,a[3]=1.a[4]=2,a[5]=1,a[6]=2。

观察可得1~3是一个可行的子串(不包括1)

1~5同样可行(不包括1)

也就是说,当他们对应的a数组值相等时,中间的串必定可行,因为中间的串没有引起值的变化,那么G和R相等。

那接下来我们该怎么做呢?

我们可以用2个for循环枚举数组a,找出值相等并且下标相差最大的两个点即为最大子串,但这样复杂度过高。

O(n)做法

我们以DP的角度考虑一个优解,使得这个过程能在线性时间内完成。如对于可行的长度为2的子串,我们只需要记录出现最早的长度为2的下标和出现最晚的下标即可。这里结合代码理解:

for(int i=0;i<str1.length();i++)
{
if(str1[i]=='G')
a[i+1]=a[i]+1;//计算a数组的值
else
a[i+1]=a[i]-1;
dp[a[i+1][1]=min(dp[a[i+1]][1],i+1);//记录最早
dp[a[i+1]][2]=max(dp[a[i+1]][2],i+1);//记录最晚
}

但是新的问题又来了,a[i+1]可能是负数,数组可没有负数的下标!其实这并不难,我们把dp的第一维扩大一倍,把中间的下标当作原来的下标零来使用,像这样:

//maxn=10000007
for(int i=0;i<str1.length();i++)
{
if(str1[i]=='G')
a[i+1]=a[i]+1;
else
a[i+1]=a[i]-1;
dp[a[i+1]+maxn+1][1]=min(dp[a[i+1]+maxn+1][1],i+1);
dp[a[i+1]+maxn+1][2]=max(dp[a[i+1]+maxn+1][2],i+1);
}

完整代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1000009;
int a[2*maxn];
string str1;
int dp[maxn*2+9][3];
int main()
{
cin>>str1;
for(int i=0;i<=maxn*2-5;i++)
dp[i][1]=100000000;//为min作预处理
dp[maxn+1][1]=0;//这里可以把maxn+1看作原来的下标0
for(int i=0;i<str1.length();i++)
{
if(str1[i]=='G')
a[i+1]=a[i]+1;
else
a[i+1]=a[i]-1;
dp[a[i+1]+maxn+1][1]=min(dp[a[i+1]+maxn+1][1],i+1);
dp[a[i+1]+maxn+1][2]=max(dp[a[i+1]+maxn+1][2],i+1);
}
int sumn=0;
for(int i=0;i<=maxn+str1.length();i++)//注意,从下标0开始
sumn=max(sumn,dp[i][2]-dp[i][1]);
cout<<sumn;
}

感谢dalao过目!

最新文章

  1. PHP用户注册与登录完整代码【4】
  2. 漫谈单点登录(SSO)(淘宝天猫)
  3. python模块之configparser
  4. 使用Spring MVC 实现 国际化
  5. 使用docker安装lamp
  6. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(六) 之 Layim源码改造右键菜单--好友、组管理功能的实现。
  7. C#创建Windows Service(Windows 服务)基础教程
  8. FFmpeg Filters Images 参数及效果图
  9. 《day16_多线程细节_Eclipse使用》
  10. DuiVision开发教程(17)-对话框
  11. LED字符设备驱动实例及测试代码
  12. SqlServer数据库的一些方法的用途
  13. maven管理的项目出现Error configuring application listener of class org.springframework.web.context.ContextL
  14. zoj3829 Known Notation --- 2014 ACM-ICPC Asia Mudanjiang Regional Contest
  15. activeX控件注册失败
  16. POJ 3624 Charm Bracelet 简单01背包
  17. 【Java学习笔记之二十六】深入理解Java匿名内部类
  18. Javascript 堆栈的模拟
  19. Huawei BGP和OSPF双边界重分布(一)
  20. openstack的Host Aggregates和Availability Zones

热门文章

  1. 对象中属性 加锁 用:volatile 关键词修饰 而 不用 synchronized 加锁
  2. redis集群搭建-3.0/4.0版本
  3. L18 批量归一化和残差网络
  4. STL迭代器的使用
  5. C. Standard Free2play --div
  6. [Asp.Net Core] Blazor Server Side 项目实践 - 切换页面时保留状态
  7. Mac安装aws-cli全过程,通过命令行上传文件到aws s3协议服务器
  8. Linux必须会的命令---也是以前记录的,ctrl+z fg 啥的 jobs 比较实用
  9. Caused by: java.lang.ClassCastException: class java.lang.Double cannot be cast to class org.apache.hadoop.io.WritableComparable
  10. .NET Core 使用MediatR CQRS模式