一个字符串若是长度为1 而且为’a’ 那么就是 a -good 字符串,
当长度大于1时, 须要知足 : 将总区间划分红一半, 其中一半全是a,另外一半必须为b-good 字符串 以此类推ios
这道题的作法比较直观,不断将字符串分段,而后递归下去,主要思想为分治,时间复杂度为标准的nlognweb
用dfs,相似于归并排序的思想,统计出上半段符合当前深度的字母,下半段符合当前深度的字母,而后递归下去便可svg
好像没有合适的剪枝方法,我剪枝三次一直是WA2,后来直接暴力ac了2333spa
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <queue> #include <cstring> using namespace std; const int N = 131080; int a[N]; int dfs(int l,int r,int d){ if(r - l == 1){ if((a[l] == d && a[r] == d + 1 )|| (a[l] == d + 1 && a[r] == d)) return 0; if(a[l] == d || a[l] == d + 1 || a[r] == d || a[r] == d + 1) return 1; return 2; } int m = (r + l - 1) / 2; int sum1 = 0,sum2 = 0; for(int i = l;i <= m;i++) if(a[i] == d) sum1++; for(int i = m + 1;i <= r;i++) if(a[i] == d) sum2++; int ans1 =(m - l + 1 - sum2) + dfs(l,m,d + 1); int ans2 =(m - l + 1 - sum1) + dfs(m + 1,r,d + 1); return min(ans1,ans2); } int main(){ int T,n; cin >> T; while(T--){ cin >> n; char str[N]; cin >> (str + 1); for(int i = 1;i <= n;i++) a[i] = str[i] - 'a' + 1; if(n == 1){ if(a[1] == 1) cout << 0 << endl; else cout << 1 << endl; continue; } cout << dfs(1,n,1) << endl;; } }