Codeforces Round #621 (Div. 1 + Div. 2) problem C Cow and Message

Cow and Message

Bessie the cow has just intercepted a text that Farmer John sent to Burger Queen! However, Bessie is sure that there is a secret message hidden inside.
The text is a string s of lowercase Latin letters. She considers a string t as hidden in string s if t exists as a subsequence of s whose indices form an arithmetic progression. For example, the string aab is hidden in string aaabb because it occurs at indices 1, 3, and 5, which form an arithmetic progression with a common difference of 2. Bessie thinks that any hidden string that occurs the most times is the secret message. Two occurrences of a subsequence of S are distinct if the sets of indices are different. Help her find the number of occurrences of the secret message!
For example, in the string aaabb, a is hidden 3 times, b is hidden 2 times, ab is hidden 6 times, aa is hidden 3 times, bb is hidden 1 time, aab is hidden 2 times, aaa is hidden 1 time, abb is hidden 1 time, aaab is hidden 1 time, aabb is hidden 1 time, and aaabb is hidden 1 time. The number of occurrences of the secret message is 6.

Input
The first line contains a string s of lowercase Latin letters (1≤|s|≤105) — the text that Bessie intercepted.

Output
Output a single integer — the number of occurrences of the secret message.

Examples
input

aaabb
output
6

input
usaco
output
1

input
lol
output
2

Note
In the first example, these are all the hidden strings and their indice sets:
a occurs at (1), (2), (3)
b occurs at (4), (5)
ab occurs at (1,4), (1,5), (2,4), (2,5), (3,4), (3,5)
aa occurs at (1,2), (1,3), (2,3)
bb occurs at (4,5)
aab occurs at (1,3,5), (2,3,4)
aaa occurs at (1,2,3)
abb occurs at (3,4,5)
aaab occurs at (1,2,3,4)
aabb occurs at (2,3,4,5)
aaabb occurs at (1,2,3,4,5)
Note that all the sets of indices are arithmetic progressions.
In the second example, no hidden string occurs more than once.
In the third example, the hidden string is the letter l.

题意
从一串选几个字符,每次选都使得选得的字符串序号数是等差的。
求每种挑选中 能挑出来的 的数量最多的。

题解

每次挑字符,挑的越多,限制越多,则数目越少。
(PS:比赛时,应该大胆假设,举几个例子验证一下)
证明:当取出字符串s的长度大于2,则一定可以从中取出至少1个恰好长度是2的字符串。(s可以看成先取出两个,在取出strlen(s) - 2个)。例如aab中可以取出2个ab。

但是取出1个例外,
aba可以取出2个a,1个ab;
aab可以取出2个a,2个ab;
abb可以取出1个a,2个ab。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 100000+10;
 
int n,m;
char s[maxn];
int cnt[110];
LL num[110][110];
 
int main() {
    scanf("%s",s+1);
    n=strlen(s+1);
    for (int i=1;i<=n;i++) {
        for (int j=0;j<26;j++) {
       	 //num[j][s[i] - 'a'] 记录取两个的数量
       	 //每次加从cnt[j]是因为 s[i] - 'a' 前每个字母有多少,就对应有多少取法,取法为s[i] 和 char(j + 'a')
       	             num[j][s[i]-'a'] += cnt[j];
        }
        cnt[s[i]-'a']++;//记录取一个的数量
    }
    LL ans=0;
    for (int i=0;i<26;i++) ans=max(ans,(LL)cnt[i]);
    for (int i=0;i<26;i++) {
        for (int j=0;j<26;j++) ans=max(ans,num[i][j]);
    }
    printf("%lld\n",ans);
    return 0;
}

思路更加清晰的代码(我的代码)

#include<bits/stdc++.h>
using namespace std;

vector <long long> a[27];
string s;
long long solve(int x, int y) {
	long long ans = 0;	
	for (int i = 0; i < a[x].size(); i++) {
		//在x之后y的个数
 		long long k = a[y].end() - lower_bound(a[y].begin(), a[y].end(), a[x][i]);
		ans +=k;
	}
	return ans;
}

int main() {
	cin >> s;
	for(int i = 0; i < s.length(); i++) {
	a[s[i] - 'a'].push_back(i);
	}
	long long ans = 0;
	//取1个 
	for(int i = 0; i < 26; i++) 
		ans = max(ans, (long long)a[i].size());
  	//取2个 
	ans = max (ans, ans * (ans - 1) / 2); //2个都是一样的字母 
	for(int i = 0; i < 26; i++) {//2个是不一样的字母 
		for(int j = 0; j < 26; j++) {
			if(i == j) continue;
	  		ans = max(ans, solve(i, j));
		}
	}
 	cout << ans << endl;
}
发布了25 篇原创文章 · 获赞 24 · 访问量 573

猜你喜欢

转载自blog.csdn.net/rainbowsea_1/article/details/104580394