<题目链接>
题目大意:
给你一段只由 'B'和'R'组成的字符串,问你在连续的区间内,"B"和"R"的差值最大是多少,输出该区间;如果对于差值相等的区间,优先输出左端点小的,左端点相同,优先输出右端点小的。
解题分析:
很明显要分两种情况讨论,一种是该区间内B比R多,第二种是该区间内R比B多。仔细思考后发现,可以将此题转化为最大连续和问题,对于B多的情况,用dp1来维护,将B看成1,R看成-1,对于R多的情况则用dp2来维护,将R看成1,B看成-1,然后就是用dp求解最大连续和即可,同时记录一下最大连续和所在的区间。
#include <cstdio>
#include <cstring>
const int M =1e5+7;
#define INF 0x3f3f3f3f
int main(){
char str[M];
scanf("%s",str+1);
int len=strlen(str+1);
int dpB[M],dpR[M];
for(int i=1;i<=len;i++){
if(str[i]=='B')dpB[i]=1;
else dpB[i]=-1;
if(str[i]=='R')dpR[i]=1;
else dpR[i]=-1;
}
int s1,e1,s2,e2; //分别记录两种情况的最优区间
dpB[0]=-1,dpR[0]=-1;
int start1,start2,end1,end2;
int mx1=-INF;
for(int i=1;i<=len;i++){ //先讨论B比R多的情况,求出B比R多的最大连续和
if(dpB[i-1]>=0)dpB[i]=dpB[i-1]+dpB[i];
else s1=i;
if(mx1<dpB[i]){
mx1=dpB[i];
start1=s1;
end1=i;
}
}
int mx2=-INF;
for(int i=1;i<=len;i++){ //讨论R比B多的情况,求出R比B多的最大连续和
if(dpR[i-1]>=0)dpR[i]=dpR[i-1]+dpR[i];
else s2=i;
if(mx2<dpR[i]){
mx2=dpR[i];
start2=s2;
end2=i;
}
}
//然后就是比较两种情况的最大连续和,并且当最大连续和相同时,按题目要求格式输出
if(mx1>mx2){
printf("%d %d\n",start1,end1);
}
else if(mx1==mx2){
if(start1<start2)
printf("%d %d\n",start1,end1);
else if(start1==start2){
printf("%d ",start1);
end1<end2?printf("%d\n",end1):printf("%d\n",end2);
}
else{
printf("%d %d\n",start2,end2);
}
}
else{
printf("%d %d\n",start2,end2);
}
return 0;
}
2018-09-17