题解:ios
考虑一开始时,左边从1开始枚举,右边从n开始枚举spa
咱们能够获得一个最大的值k。code
可是若是这样依次枚举,复杂度确定是n^3,是不行的blog
考虑如何利用上一次的结果,若是咱们把1和n同时去掉ci
就能够利用上一步的结果了(由于剩下的匹配仍然没有改变)string
这样依次扫一遍,每次O(n)的时间能够获得O(n)对匹配对应的最大值io
因此均摊复杂度就是O(n^2)class
#include <iostream> #include <cstring> #include <cstdio> using namespace std; char S[5005]; bool dp[5005][5005]; int T, m; int myabs(int x) { return x < 0 ? -x : x; } int main() { cin>>T; while(T--){ cin>>m; cin>>S; int ANS = 0, n = strlen(S); memset(dp, 0, sizeof(dp)); for(int i = 0; i < n; i++) for(int j = n-1; j >= 0; j--){ if(i >= j) break; if(dp[i][j]) continue; int sx = i, sy = j, k = 0, ans = 0; while(sx < sy){ if(sx+k >= sy-k){ while(sx < sy){ dp[sx][sy] = 1; ANS = max(k, ANS); k--; sx++; sy--; } break; } if(ans + myabs(S[sx+k]-S[sy-k]) <= m) ans += myabs(S[sx+k] - S[sy-k]), k++; else{ while(ans + myabs(S[sx+k]-S[sy-k]) > m && k > 0){ dp[sx][sy] = 1; ANS = max(k, ANS); ans -= myabs(S[sx] - S[sy]); k--; sx++; sy--; } if(ans + myabs(S[sx+k] - S[sy-k]) <= m){ ans += myabs(S[sx+k] - S[sy-k]); k++; } else { sx++; sy--; } } } } cout<<ANS<<endl; } return 0; }