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

来源:互联网 发布:股票自动化交易编程 编辑:程序博客网 时间:2024/06/07 01:32

题目链接:

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 longconst 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 longconst 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]);    }}



阅读全文
0 0
原创粉丝点击