题目:题目目标串有类似递归的要求。可以看出在左边界或者有边界存在连续的字符且是上个连续字符长度的一半,字符则是上个字符的下一个字符。
思路:容易想到二分,深度log(n),则复杂度O(n*log(n))。
我们可以直接分两种情况:
①左半边连续字符相同
②右半边连续字符相同
我们把这个作为递归条件即可,统计花费的时候我们只需要判断当前连续部分字符是不是我们的目标字符来计算花费即可。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <queue> 5 #include <vector> 6 #include <cmath> 7 8 using namespace std; 9 10 #define ll long long 11 #define pb push_back 12 #define fi first 13 #define se second 14 15 const int N = 2e5 + 10; 16 char s[N]; 17 int len; 18 19 int dfs(int l, int r, char c) 20 { 21 22 if(l == r){ 23 if(s[l] == c) return 0; 24 else return 1; 25 } 26 int mid = (l + r) >> 1; 27 int min_cost = 2e9; 28 int a1 = 0, b1 = 0; 29 for(int i = l; i <= mid; ++i){ 30 if(s[i] != c) a1++; 31 } 32 33 min_cost = min(min_cost, a1 + dfs(mid + 1, r, c + 1)); 34 a1 = b1 = 0; 35 for(int i = mid + 1; i <= r; ++i){ 36 if(s[i] != c) a1++; 37 } 38 39 min_cost = min(min_cost, a1 + dfs(l, mid, c + 1)); 40 41 return min_cost; 42 } 43 44 void solve() 45 { 46 int T; 47 cin >> T; 48 while(T--){ 49 cin >> len >> (s + 1); 50 cout << dfs(1, len, 'a') << endl; 51 52 } 53 } 54 55 int main() 56 { 57 ios::sync_with_stdio(false); 58 cin.tie(0); 59 cout.tie(0); 60 solve(); 61 62 return 0; 63 }