The main effect of the topic
To a string, you can abbreviate the same part of the Continuum to K (s), S is a string, and K denotes a continuous identical S
For example, Abgogogogo can be abbreviated to AB4 (GO). You can also nest abbreviations, such as
"Nowletsgogogoletsgogogo", abbreviated as "Now2 (Lets3 (GO)")
Ideas
An interval DP, but this is not a good question.
F (I, j) represents the minimum number of digits of the i~j bit of a string
So
F (i, j) = min{
min{f (i,k) +f (K+1, J), I<=k<j},
min{Digitnum (k) +f[l][l+k-1]+2 if the string can be duplicated by the first K string
}
Digitnum (k) indicates the number of digits K
Whether the interval (i, j) is composed of consecutive K-strings, directly using the time of O (n) to determine
Code
/**========================================== * is a solution for ACM/ICPC problem * * @source: uva-1351 String Compression * @type: Interval DP * @author: Shuangde * @blog: blog.csdn.net/shuangde800 * @email: zengshuangde@gmail.com *======= ====================================*/#include <iostream> #include <cstdio> #include <algorithm> #
include<vector> #include <queue> #include <cmath> #include <cstring> using namespace std;
typedef long long Int64;
const int INF = 0X3F3F3F3F;
Const double PI = ACOs (-1.0);
const int MAXN = 210;
Char STR[MAXN];
int F[MAXN][MAXN], Len; Determine whether the string interval [L,r] consists of a bool check (int l, int r, int k) {int len = r-l+1; int i = 0; while (I < k) {for int P = 1; l+p*k+i<=r;
++P) {if (Str[l+i]!= Str[l+p*k+i]) return false;} ++i;
return true; ///Calculate number x There are several//http://www.bianceng.cn inline int digitnum (int x) {int cnt = 0; while (x > 0) {++cnt; x/=} R
Eturn CNT;
int main () {
int ncase;
scanf ("%d", &ncase);
while (ncase--) {scanf ("%s", str+1); len = strlen (str+1);
for (int i = 1; I <= len; ++i) F[i][i] = 1;
for (int d = 2; d <= len. ++d) {for (int l = 1; l+d-1 <= len; ++l) {int r = l + d-1;
F[l][r] = INF;
int& ret = f[l][r];
for (int k=l; k<r; ++k) ret = min (ret, f[l][k]+f[k+1][r]); for (int k = 1; k <= d/2; ++k) {if (d%k!=0) continue; if (check (L, r, K)) {ret = min (ret, digitnum (d/k) + f[l][l+k-1] + 2
);
}} printf ("%d\n", F[1][len]);
return 0; }