Question address: http://uva.onlinejudge.org/index.php? Option = com_onlinejudge & Itemid = 8 & page = show_problem & problem = 2547
Question meaning:
Give you a string that is an integer multiple of K. You need to divide it into segments of each length.
You can re-orchestrate each segment
Several consecutive letters are considered as a block.
There are at least a few blocks.
Solution:
For each segment, we can know the minimum block, that is, there are several types of letters in it, which are recorded as chunk [I]
We set f [I] [J] to the minimum number of J-bits in segment I at the end.
Then, when the L of the nth I-1 block is placed at the end
If it is the same as the first block in I, a block can be merged.
F [I] [J] = min (F [I] [J], F [I-1] [l] + chunk-1 );
Otherwise
F [I] [J] = min (F [I] [J], F [I-1] [l] + chunk );
# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; const int maxn = 1010; int f [maxn] [maxn]; char s [maxn]; bool vis [maxn]; int main () {int t; scanf ("% d", & T); While (t --) {int K, Len; scanf ("% d", & K); scanf ("% s", S); Len = strlen (s); memset (F, 0x3f3f3f, sizeof (f )); for (INT I = 1; I <= Len/K; I ++) {memset (VIS, false, sizeof (VIS); For (Int J = 1; j <= K; j ++) {vis [s [(I-1) * k + J-1] = true;} int chunk = 0; For (Int J = 'a'; j <= 'Z'; j ++) if (vis [J]) chunk ++; if (I = 1) {for (Int J = 1; j <= K; j ++) f [1] [J] = chunk; continue ;} for (Int J = 1; j <= K; j ++) {int rear = (I-1) * k + J-1; For (int l = 1; L <= K; l ++) {int pre = (I-2) * k + L-1; if (vis [s [pre] & (chunk = 1 | s [pre]! = S [rear]) f [I] [J] = min (F [I] [J], F [I-1] [l] + chunk-1 ); else f [I] [J] = min (F [I] [J], F [I-1] [l] + chunk) ;}} int ans = 0x3f3f3f; for (INT I = 1; I <= K; I ++) ans = min (ANS, F [Len/K] [I]); printf ("% d \ n", ANS);} return 0 ;}