1 //dp[i][j][k]表示第i组以字母('a'+j)开头,以字母('a'+k)结尾,最多能组合成多少对
2 //a[i][j]表示第i组中有哪些字母,a[i][j]为1表示有字母('a'+j);
3 //c[i]表示第i组中不同字母的个数
4 //Max[i]表示第i组dp[i][j][k]最大的值
5 //最后结果便为sum(c[i(0, len-1)]) - Max[len-1]; (len为组数)
6 #include <iostream>
7 #include <cstring>
8 using namespace std;
9 int dp[1001][26][26], a[1001][26], c[1001], Max[1001];
10 int main(){
11 char s[1001];
12 int i, j, t, k, l, ans;
13 cin>>t;
14 while(t--){
15 cin>>l>>s;
16 int len = strlen(s) / l;
17 for(i = 0; i < len; ++i){
18 Max[i] = c[i] = 0;
19 for(j = 0; j < 26; ++j){
20 a[i][j] = 0;
21 for(k = 0; k < 26; ++k)
22 dp[i][j][k] = 0;
23 }
24 }
25 for(i = 0; i < len; ++i){
26 for(j = 0; j < l; ++j)
27 a[i][s[i * l + j] - 'a'] = 1;
28 for(j = 0; j < 26; ++j)
29 if(a[i][j]) c[i]++;
30 }
31 for(i = 1; i < len; ++i){//i组
32 for(j = 0; j < 26; ++j){ //字母('a'+j)开头
33 for(k = 0; k < 26; ++k){ //字母('a'+k)结尾
34 if((c[i] == 1 || j != k) && a[i][j] && a[i][k]){
35 //在第i-1组中是否存在字母('a'+j)
36 if(a[i-1][j]){
37 int temp = 0;
38 //若存在则找i-1组中以字母('a'+j)结尾的最大值
39 for(int x = 0; x < 26; ++x)
40 if(a[i-1][x]) temp = max(temp, dp[i-1][x][j]);
41 dp[i][j][k] = temp + 1;
42 }
43 //若不存在则等于第i-1组的最大值
44 else
45 dp[i][j][k] = Max[i-1];
46 Max[i] = max(Max[i], dp[i][j][k]);
47 }
48 }
49 }
50 }
51 ans = 0;
52 //for(i = 0; i < len; ++i) cout<<i<<"**"<<c[i]<<"**"<<Max[i]<<endl;
53 for(i = 0; i < len; ++i) ans += c[i];
54 ans -= Max[len-1];
55 cout<<ans<<endl;
56 }
57 return 0;
58 }
2 //a[i][j]表示第i组中有哪些字母,a[i][j]为1表示有字母('a'+j);
3 //c[i]表示第i组中不同字母的个数
4 //Max[i]表示第i组dp[i][j][k]最大的值
5 //最后结果便为sum(c[i(0, len-1)]) - Max[len-1]; (len为组数)
6 #include <iostream>
7 #include <cstring>
8 using namespace std;
9 int dp[1001][26][26], a[1001][26], c[1001], Max[1001];
10 int main(){
11 char s[1001];
12 int i, j, t, k, l, ans;
13 cin>>t;
14 while(t--){
15 cin>>l>>s;
16 int len = strlen(s) / l;
17 for(i = 0; i < len; ++i){
18 Max[i] = c[i] = 0;
19 for(j = 0; j < 26; ++j){
20 a[i][j] = 0;
21 for(k = 0; k < 26; ++k)
22 dp[i][j][k] = 0;
23 }
24 }
25 for(i = 0; i < len; ++i){
26 for(j = 0; j < l; ++j)
27 a[i][s[i * l + j] - 'a'] = 1;
28 for(j = 0; j < 26; ++j)
29 if(a[i][j]) c[i]++;
30 }
31 for(i = 1; i < len; ++i){//i组
32 for(j = 0; j < 26; ++j){ //字母('a'+j)开头
33 for(k = 0; k < 26; ++k){ //字母('a'+k)结尾
34 if((c[i] == 1 || j != k) && a[i][j] && a[i][k]){
35 //在第i-1组中是否存在字母('a'+j)
36 if(a[i-1][j]){
37 int temp = 0;
38 //若存在则找i-1组中以字母('a'+j)结尾的最大值
39 for(int x = 0; x < 26; ++x)
40 if(a[i-1][x]) temp = max(temp, dp[i-1][x][j]);
41 dp[i][j][k] = temp + 1;
42 }
43 //若不存在则等于第i-1组的最大值
44 else
45 dp[i][j][k] = Max[i-1];
46 Max[i] = max(Max[i], dp[i][j][k]);
47 }
48 }
49 }
50 }
51 ans = 0;
52 //for(i = 0; i < len; ++i) cout<<i<<"**"<<c[i]<<"**"<<Max[i]<<endl;
53 for(i = 0; i < len; ++i) ans += c[i];
54 ans -= Max[len-1];
55 cout<<ans<<endl;
56 }
57 return 0;
58 }