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 <bits/stdc++.h>
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

posted @ 2018-09-17 19:30  悠悠呦~  阅读(252)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end