Codefoces Gym 101652 【最大连续和】

<题目链接>

题目大意:

给你一段只由 '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

猜你喜欢

转载自www.cnblogs.com/00isok/p/9664354.html