每次将字符串分成两段,取修改左边和修改右边的最小值
分治处理即可
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 200010;
int T,n,m;
char s[maxn];
//sl[maxn],sr[maxn];
int calc(int l,int r,char ch){
if(l+1==r){
return s[l]!=ch;
}
int cnt1 = 0,cnt2 = 0;
int mid = (l+r)>>1;
for(int i=l;i<r;++i){
if(i<mid) cnt1 += (s[i] != ch);
else cnt2 += (s[i] != ch);
}
return min(cnt1+calc(mid,r,ch+1),cnt2+calc(l,mid,ch+1));
}
ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
int main(){
T = read();
while(T--){
n = read();
scanf("%s",s);
printf("%d
",calc(0,n,'a'));
}
return 0;
}