2017.10.1 国庆清北 D1T1 zhx的字符串题
题目背景
2017国庆清北D1T1
题目描述
你是能看到第一题的 friends 呢。
——hja
何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx。何大爷今天为
字符串定义了新的权值计算方法。一个字符串由小写字母组成,字符串的权值
被定义为其中出现次数最多的字符的次数减去出现次数最少的字符的次数。 (注
意,在讨论出现最少的字符的时候,该字符必须至少出现一次)现在何大爷给
你一个字符串,何大爷想知道这个字符串的所有子串中权值最大的权值是多
少?
输入输出格式
输入格式:
第一行一个整数n,代表字符串的长度。
接下来一行n个小写字母,代表该字符串。
输出格式:
一行一个整数代表答案。
输入输出样例
输入样例#1:
10 aabbaaabab
输出样例#1:
3
说明
对于30%的数据,1<=n<=100
对于60%的数据,1 ≤ n ≤ 1000。
对于100%的数据,1 ≤n ≤ 10^6 .
不过,luogu神机。。
1000ms时限TLE仨点
3000ms时限AC
我不就改了改时限嘛,最高的点跑了不到500ms,然后就TLE了?
1 /* 2 sum[r][a]-sum[r][b]-sum[l-1][a]-sum[l-1][b] 3 用minv[a][b]代替sum[l-1][a]-sum[l-1][b] 4 5 sum[a][b]表示1~a中字母b出现的次数 6 minv[a][b]表示a与b个数的差的最小值 7 p[a][b]表示minv[a][b]出现的位置 8 */ 9 #include<iostream> 10 #include<cstdio> 11 #include<algorithm> 12 #include<cstring> 13 #include<cmath> 14 using namespace std; 15 16 int n,ans,minv[26][26],p[26][26],sum[26],last[26]; 17 char s[1000005]; 18 19 int main() 20 { 21 scanf("%d",&n); 22 scanf("%s",s+1); 23 for(int i=1;i<=n;i++) 24 { 25 int c=s[i]-'a'; 26 last[c]=i; 27 sum[c]++; 28 for(int j=0;j<26;j++) 29 { 30 if(c!=j&&sum[j]) //自己不能与自己比较,而且j必须出现过 31 { 32 ans=max(ans,sum[c]-sum[j]-minv[c][j]-(last[j]==p[c][j])); //last[j]==p[c][j]:如果j最后一次出现是在minv[c][j]最小的时候,那么要将这个j算上,因为如果不算这个j那么j就没出现过了 33 ans=max(ans,sum[j]-sum[c]-minv[j][c]-(last[j]==p[j][c])); //同理 34 } 35 } 36 for(int j=0;j<26;j++) 37 { 38 if(sum[c]-sum[j]<minv[c][j]) minv[c][j]=sum[c]-sum[j],p[c][j]=i; //更新差的最小值和出现位置 39 if(sum[j]-sum[c]<minv[j][c]) minv[j][c]=sum[j]-sum[c],p[j][c]=i; 40 } 41 } 42 printf("%d",ans); 43 return 0; 44 }