Now we have a string and try to find its shortest compressed character length (brackets count). For example, AAAAAABCABC = 6(A)BCABC, which has a compressed length of 9.
constint maxn = 210; int f[maxn][maxn]; // minium number of division int len; // the length of the string char s[maxn];
intget(int x){ //calculate the digits int sum = 0; while (x) { sum++; x /= 10; } return sum; }
intmain(){ scanf("%s", s + 1); memset(f, 0x3f, sizeof(f)); // initialize len = strlen(s + 1);
// for (int i = 1; i <= len; ++i) { //Pre-processed sub-intervals of length 1 f[i][i] = 1; }
// expand the length of sub-intervals for (int le = 2; le <= len; ++le) { // the length of the sub-intervals for (int l = 1; l + le - 1 <= len; ++l) { // the initial position of the sub-intervals f[l][l + le - 1] = min(le, f[l][l + le - 1]); // Treat the whole interval as a subinterval, initialised to the length of the substring // Enumerated intervals have several complete subintervals inside them with the same first character as the interval for (int t = 1;; t++) { bool flag = true; int st = l + t * le; if (st + le - 1 > len) break;
// Determine if the internal subintervals are identical for (int p = 1; p <= le; p++) { if (s[l + p - 1] != s[st + p - 1]) { flag = false; break; } }
// If the internal subintervals are not identical, end the enumeration if (!flag) break;
// Update the minimum number of divisions of a subinterval f[l][l + (t + 1) * le - 1] = min(min(le + get(t + 1) + 2, (t + 1) * le), f[l][l + (t + 1) * le - 1]); // where le + get(t + 1) + 2 means that the number of internal subintervals is expressed as the required length of the string // (t + 1) * le denotes the number of partitions of the interval in terms of t+1 identical substrings }
// Enumerate from the middle position and update the minimum number of divisions of the subinterval int j = l + le - 1; for (int k = l; k < j; k++) { f[l][j] = min(f[l][j], f[l][k] + f[k + 1][j]); } } }