题目链接:http://codeforces.com/problemset/problem/814/C
题意:给你一个字符串,然后开始询问,每次给你一个字母ch,和个数m,可以替换原串字母,问你最多有多少个字母ch
解析:我当时写时,没看时间复杂度,直接写尺取法(复杂度n*q),没想到最后终测竟然过了,与这个题:http://blog.csdn.net/qq_34287501/article/details/72899944很像
代码:
#include<bits/stdc++.h>
#define N 2009
using namespace std;
char s[N];
int main()
{
int n, m, q;
char ch;
scanf("%d", &n);
getchar();
gets(s);
scanf("%d", &q);
while(q--)
{
scanf("%d %c", &m, &ch);
int l, r; l = r = 0;
for(int i = 0; i < n; i++)
{
if(m <= 0 && s[i] != ch) break;
if(s[i] != ch) m--;
r++;
}
int ans = r - l;
for(int i = r; i < n; i++)
{
if(s[i] != ch)
{
ans = max(ans, i - l);
while(s[l] == ch) l++;
l++;
}
}
ans = max(ans, n - l);
printf("%d\n", ans);
}
return 0;
}
代码2(泰神写的DP,复杂度min(n^2, q)):
dp[i][j] 以第i个字符结尾,改变j次的最长长度, 决策是第i个字符改,或者不改
#include <bits/stdc++.h>
using namespace std;
struct Query
{
int index;
int m;
};
char str[1601];
vector<Query> query[30];
int ans[200500];
int dp[1511][1511];
int maxm[1511];
int n;
void Solve(char ch)
{
memset(dp, 0, sizeof(dp));
memset(maxm, 0, sizeof(maxm));
for (int i = 1; i <= n; ++i)
{
if (str[i] == ch)
{
dp[i][0] = dp[i - 1][0] + 1;
}
else
{
dp[i][0] = 0;
}
}
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= i; ++j)
{
if (str[i] == ch)
{
dp[i][j] = dp[i - 1][j] + 1;
}
else
{
dp[i][j] = 0;
}
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
maxm[j] = max(maxm[j], dp[i][j]);
}
}
for (int i = 0; i < query[ch - 'a'].size(); ++i)
{
ans[ query[ch - 'a'][i].index ] = maxm[ query[ch - 'a'][i].m ];
}
}
int main()
{
scanf("%d", &n);
scanf("%s", str + 1);
int q;
scanf("%d", &q);
for (int i = 1; i <= q; ++i)
{
int m;
char c;
scanf("%d %c", &m, &c);
query[c - 'a'].push_back(Query{i, m});
}
for (int i = 0; i < 26; ++i)
{
Solve('a' + i);
}
for (int i = 1; i <= q; ++i)
{
printf("%d\n", ans[i]);
}
return 0;
}