描述
题解
这个题要难为死我了,搞半天也不知道怎么做……
首先我们可以假设
A
一定在
简单的说就是,将整个区间划分为两份,然后左右各有一个序列,这个序列是贪心的,贪心的过程利用尺取法来维护最优解,而这里我们需要对区间的划分进行枚举,并且由于尺取法每次都是往左右各推移一位,所以我们需要考虑到中间是奇数个元素还是偶数个元素,所以此时的划分又要分为两种情况了。
也许我说的有些乱,结合代码看看吧,应该还是比较容易理解的了。
代码
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 5555;
const int MAXM = MAXN >> 1;
int n, m;
int cnt, ans;
int tmp[MAXM];
char s[MAXN];
void check()
{
int dis = 0, dis2 = 0, x1 = 0, x2 = 0;
while (x2 < cnt)
{
dis2 += tmp[x2++];
while (dis2 > m)
{
dis2 -= tmp[x1++];
}
dis = max(dis, x2 - x1);
}
ans = max(ans, dis);
}
void solve()
{
n = (int)strlen(s + 1);
ans = 0;
for (int i = 1; i <= n; i++)
{
cnt = 0;
int x1 = i - 1;
int x2 = i + 1;
while (x1 > 0 && x2 <= n)
{
tmp[cnt++] = abs(s[x1--] - s[x2++]);
}
check();
}
for (int i = 1; i <= n; i++)
{
cnt = 0;
int x1 = i;
int x2 = i + 1;
while (x1 > 0 && x2 <= n)
{
tmp[cnt++] = abs(s[x1--] - s[x2++]);
}
check();
}
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
scanf("%d%s",&m, s + 1);
solve();
printf("%d\n", ans);
}
return 0;
}