Codeforces Round #418 (Div. 2) C. An impassioned circulation of affection

xiaoxiao2021-02-28  104

题目链接:

http://codeforces.com/contest/814/problem/C

题意:

给出一个长为n的字符串s,接下来有q次询问,每次询问给出正整数m和字符c,问在字符串中最多添加m个字符c后字符串中最长的仅含c的连续子串的长度为多少

题解:

因为q<=2e5所以易想到这题需要将答案保存到数组中,这样就需要dp处理字符串

设dp[i][j][k]为从第i个下标开始选择修改k个字符后,仅含字符'a'+j的连续子串的最长长度为多少。

当i>=1,dp[i][j][k] = dp[i-1][j][k-p]       (当s[i]=='a'+j时p=0,否则p=1)

当i==0,dp[i][j][k] = q        (当k大于0或s[i]=='a'+j时q=1否则q=0)

然后因为给出m与c后dp的第一位无意义,所以可以舍去将dp[i][j][k]中有用的信息保存为ans[i][j],ans[i][j]表示修改i个字符为'a'+j字符后字符串的仅含'a'+j的连续子串最长长度

#include<bits/stdc++.h> using namespace std; #define MAX_N 40005 #define inf 0x3f3f3f3f #define LL long long #define uLL unsigned long long const LL mod = 1e9+7; const LL INF = 1e18; typedef pair<int, int>P; const double eps = 1e-6; int dp[1505][26][1505]; int ans[1505][26]; int main() { int n; scanf("%d", &n); char s[1505]; scanf("%s", s); memset(dp, 0, sizeof(dp)); memset(ans, 0, sizeof(ans)); for(int i=0; i<n; i++) { for(int j=0; j<26; j++) { for(int k=0; k<=n; k++) { if(i) { if(k) dp[i][j][k] = dp[i-1][j][k-(s[i]!=('a'+j))] + 1; else dp[i][j][k] = (s[i]=='a'+j)?(1 + dp[i-1][j][k]):0; } else { if(s[i]=='a'+j) dp[i][j][k] = 1; else dp[i][j][k] = (k>0); } } } } for(int i=0; i<26; i++) { for(int j=0; j<n; j++) { for(int k=0; k<=n; k++) { ans[k][i] = max(ans[k][i], dp[j][i][k]); } } } int q; scanf("%d", &q); while(q--) { int m; char c; scanf("%d %c", &m, &c); printf("%d\n", ans[m][c-'a']); } }

再提供另一种尺取法,更好编码和理解

#include<bits/stdc++.h> using namespace std; #define MAX_N 40005 #define inf 0x3f3f3f3f #define LL long long #define uLL unsigned long long const LL mod = 1e9+7; const LL INF = 1e18; typedef pair<int, int>P; const double eps = 1e-6; int dp[26][1505]; int n, q; string s; void init() { for(int i=0; i<26; i++) { for(int j=1; j<=n; j++) { char c = ('a'+i); int l = 0; int r = 0; int tmp = s[0]!=c; int ans = 0; while(r>=l && r<n) { if(j>=tmp) ans = max(ans, r-l+1); if(j>=tmp) { r++; tmp += (s[r]!=c); } else { tmp -= (s[l]!=c); l++; } } dp[i][j] = ans; } } } int main() { cin >> n; cin >> s; cin >> q; init(); while(q--) { int m; char c; scanf("%d %c", &m ,&c); printf("%d\n", dp[c-'a'][m]); } }

转载请注明原文地址: https://www.6miu.com/read-65790.html

最新回复(0)