a
【问题描述】
你是能看到第一题的 friends 呢。
——hja
何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx。
何大爷今天为字符串定义了新的权值计算方法。一个字符串
由小写字母组成,字符串的权值被定义为其中出现次数最多
的字符的次数减去出现次数最少的字符的次数。 (注意,在
讨论出现最少的字符的时候,该字符必须至少出现一次)现在
何大爷给你一个字符串,何大爷想知道这个字符串的所有子串
中权值最大的权值是多少?
【输入格式】
第一行一个整数?,代表字符串的长度。
接下来一行?个小写字母,代表该字符串。
【输出格式】
一行一个整数代表答案。
【样例输入】
10
aabbaaabab
【样例输出】
3
【数据范围与规定】
3。
60%的数据,1 ≤ ? ≤ 1000。
对于100%的数据,1 ≤ ? ≤ 10 6 .
题目大意:
求一个字符串子串的最多出现次数-最少出现次数的最大值。
题解:
30分做法O(n^3)枚举区间 扫最大最小值
60分做法O(26n^2)枚举区间 前缀和求最大最小值
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,maxx,minn,ans,sum[1020][26]; char s[1020]; int main(){ scanf("%d",&n);scanf("%s",s+1); for(int i=1;i<=n;i++){ for(int j=1;j<=26;j++)sum[i][j]=sum[i-1][j]; int z=s[i]-'a'+1; sum[i][z]=sum[i-1][z]+1; } for(int i=1;i<=n;i++){ for(int j=i;j<=n;j++){ if(i==j){ ans=max(ans,0); continue; } maxx=-1;minn=100000; for(int k=1;k<=26;k++){ int z=sum[j][k]-sum[i-1][k]; if(z)minn=min(minn,z); maxx=max(maxx,z); } ans=max(ans,maxx-minn); } } printf("%d\n",ans); return 0; }