思路:
对于题目中的一个查询(m, c),枚举子区间[l, r](0 <= l <= r < n),若该区间满足其中的非c字符个数x不超过m,则可以将其合法转换为一个长度为r-l+1的全c子序列,可以使用动态规划以O(n2)的复杂度计算,然而O(n2q)的复杂度还是太高了。于是先离线把26n中情况都计算出来,再打表即可。复杂度O(26n2+q)。
实现:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 const int MAXN = 1505; 6 7 int n, q, m, ans[30][MAXN]; 8 string s; 9 char c; 10 11 int main() 12 { 13 cin >> n >> s; 14 for (int k = 0; k < 26; k++) 15 { 16 char tmp = 'a' + k; 17 for (int i = 0; i < n; i++) 18 { 19 int cnt = 0; 20 for (int j = i; j < n; j++) 21 { 22 if (s[j] != tmp) cnt++; 23 ans[k][cnt] = max(ans[k][cnt], j - i + 1); 24 } 25 } 26 for (int i = 1; i < MAXN; i++) 27 ans[k][i] = max(ans[k][i], ans[k][i - 1]); 28 } 29 cin >> q; 30 for (int i = 0; i < q; i++) 31 { 32 scanf("%d %c", &m, &c); 33 printf("%d ", ans[c - 'a'][m]); 34 } 35 }