題解: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; }