给定一个由小写字母构成的字符串 s。
我们称字符串 t 隐藏于字符串 s 中,如果它满足:
- 存在一个字符串 s 的子序列,与其一一对应。
- 该子序列的各个元素的下标可以构成一个等差序列。
例如,字符串 aab 就隐藏于字符串 aaabb 中,因为 aaabb 的第 1,3,5 个元素刚好可以构成 aab,而这恰好是一个公差为 2 的等差数列。
字符串 t 可能隐藏于字符串 s 中多次,这取决于共有多少个 s 的不同子序列满足与字符串 t 一一对应,且各个元素下标可以构成一个等差数列。
例如,在字符串 aaabb 中,a 隐藏了 3 次,b 隐藏了 2 次,ab 隐藏了 6 次…
现在,请你求出字符串 s 中,隐藏次数最多的字符串一共隐藏了多少次?
输入格式
一个字符串 s。
输出格式
一个整数,表示字符串 s 中,隐藏次数最多的字符串的隐藏次数。
数据范围
前三个测试点满足 1≤|s|≤5。
所有测试点满足 1≤|s|≤105。
输入样例1:
aaabb
输出样例1:
6
输入样例2:
abcde
输出样例2:
1
输入样例3:
lol
输出样例3:
2
算法:
如果字符串长度大于2,那么它下标组成等差数列可以由前两个下标确定,只需要枚举前两个元素,那么由着两元素组成的等差数列一定包含它;
由于长度大于 2 的子序列必然包含长度为 2 的子序列,所以只需要考虑长度不超过 2 的;
s[26]来统计只出现一次的字符;
f[26][26]来统计前两个元素出现的次数;
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1e5 +10;
LL s[26],f[26][26];
char str[N];
int main(){
scanf("%s",&str);
LL res = 0;
for(int i = 0; str[i]; i++){
int t = str[i] - 'a';
for(int j = 0; j < 26; j++){
f[j][t] += s[j];
res = max(res,f[j][t]);
}
s[t]++;
res = max(res,s[t]);
}
cout<<res<<endl;
return 0;
}