题目描述
绿宝石用‘G’表示,红宝石用‘R
思路:
这道题需要使用前缀和算法。
接下来,我们要考虑什么条件能够说明宝石完全匹配。将'G'和'R'转化为1和-1有一个好处:这样如果我们将一个1和一个-1放在一起,组合而成的数的特点即为1+(-1)=0.
这样思考之后,我们就可以维护这个数字串的前缀和数组:1 0 1 2 1 2。当在前缀和数组中,两个数的值相等,则说明宝石已经完全匹配。
这样我们就有了写代码的思路:建立一个数组f,f[i]表示从第i块宝石往前推,所构成的稳定的宝石串的最大长度。而计算整个宝石串内稳定的串的最大长度,只需要对f数组取max
1 #include<iostream>
2 #include<string>
3 using namespace std;
4 string s;
5 int n,i,j,ans;
6 int sum[1000005]={0},f[1000005]={0};
7 int main(){
8 cin>>s;
9 n=s.length();
10 for(i=1;i<=n;i++){
11 if(s[i-1]=='G'){ //绿宝石代表1
12 sum[i]=sum[i-1]+1;
13 }else if(s[i-1]=='R'){ //红宝石代表-1
14 sum[i]=sum[i-1]-1;
15 }
16 }
17 ans=-99999;
18 for(i=1;i<=n;i++) {
19 for(j=i;j>=1;j--) {
20 if(sum[i]==sum[j]) {
21 f[i]=i-j;
22 }
23 }
24 if(ans<f[i]){
25 ans=f[i];
26 }
27 }
28 cout<<ans<<endl;
29 return 0;
30 }
为什么?
这份代码的问题在于它枚举的边界出现了错误。
我们来考虑,当数据为GGRRGR
那么这个问题如何解决呢?只需要将sum[0]=0加入到枚举的范围中即可。
1 #include<iostream>
2 #include<string>
3 using namespace std;
4 string s;
5 int n,i,j,ans;
6 int sum[1000005]= {0},f[1000005]= {0};
7 int main() {
8 cin>>s;
9 n=s.length();
10 for(i=1; i<=n; i++) {
11 if(s[i-1]=='G') { //绿宝石代表1
12 sum[i]=sum[i-1]+1;
13 } else if(s[i-1]=='R') { //红宝石代表-1
14 sum[i]=sum[i-1]-1;
15 }
16 }
17 ans=-99999;
18 for(i=1; i<=n; i++) {
19 for(j=i; j>=0; j--) {//枚举到0
20 if(sum[i]==sum[j]) {
21 f[i]=i-j;
22 }
23 }
24 if(ans<f[i]) {
25 ans=f[i];
26 }
27 }
28 cout<<ans<<endl;
29 return 0;
30 }