题目链接:http://codeforces.com/contest/814/problem/C
题意:给你一个长度为n的字符串,然后给你q个询问,m和字符c,代表修改m个字符,连续的c最长是多长。
分析:字符串长度是1500,然后询问是200000,我们可以预处理,把他能询问到的全部存储下来,问题转化为任意修改i个字符,问你连续的字符c最长多长。这里我们可以dp求一个把i到j全部变为字符c最少需要变换k个字符,然后将变换k个字符所能形成的连续串长度存到result[c][k],那么他在询问的时候,我们只需要输出result[c][m]即可。
dp求把i到j全部变为字符c,定义数组dp[26][1500][1500],对于dp[c][i][j]如果a[j]==c,那么dp[c][i][j]=dp[c][i][j-1],然后result[dp[c][i][j]]=max(result[c][dp[c][i][j]],j-i+1)。当然要注意可能把1到n全部变为c字符需要的变换很少,他询问你变换多个,那么长度还是n,因此result如果等于0,那么就等于他的前一个。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 char a[1505]; 5 char c[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; 6 int dp[26][1505][1505]; 7 int result[26][1505]; 8 map<char ,int >mp; 9 int main(){ 10 ios_base::sync_with_stdio(0); 11 cin.tie(0); 12 memset(result,0,sizeof(result)); 13 memset(dp,0,sizeof(dp)); 14 for(int i=0;i<=25;i++){ 15 mp[c[i]]=i; 16 } 17 int n,q; 18 cin>>n; 19 for(int i=1;i<=n;i++){ 20 cin>>a[i]; 21 } 22 for(int q=0;q<=25;q++){ 23 for(int i=1;i<=n;i++){ 24 for(int j=i;j<=n;j++){ 25 if(a[j]==c[q]){ 26 dp[q][i][j]=dp[q][i][j-1]; 27 28 } 29 else { 30 dp[q][i][j]=dp[q][i][j-1]+1; 31 } 32 result[q][dp[q][i][j]]=max(result[q][dp[q][i][j]],j-i+1); 33 } 34 } 35 } 36 for(int i=0;i<=25;i++){ 37 for(int j=1;j<=n;j++){ 38 if(result[i][j]==0){ 39 result[i][j]=result[i][j-1]; 40 } 41 } 42 } 43 cin>>q; 44 char d; 45 int num; 46 for(int i=1;i<=q;i++){ 47 cin>>num>>d; 48 cout<<result[mp[d]][num]<<endl; 49 } 50 return 0; 51 }