F[ i ][ j ]表示将字符串压缩 i , j所需要的最小代价
枚举转移
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 105
using namespace std;
bool vis[N][N];
int F[N][N],n;
char s[N];
bool check(int l,int r,int i) {
int t = 0;
for (int j=l;j<=r;j++) {
t++;
t = (t-1) % (i - l + 1) + 1;
if (s[j] != s[l+t-1]) return false;
}
return true;
}
int L(int x) {
int tmp = 0;
while (x) { tmp++; x = x / 10; }
return tmp;
}
int DP(int l,int r) {
if (l == r) return 1;
if (vis[l][r]) return F[l][r];
vis[l][r] = 1;
F[l][r] = r - l + 1;
for (int i=l;i<=r-1;i++) {
F[l][r] = min( DP(l,i) + DP(i+1,r) , F[l][r]);
if ((r - l + 1) % (i - l + 1) == 0) {
int t = (r - l + 1) / (i - l + 1);
if (check(l,r,i))
F[l][r] = min(L(t) + DP(l,i) + 2 , F[l][r]);
}
}
return F[l][r];
}
int main()
{
scanf("%s",s+1);
n = strlen(s+1);
int ans = DP(1,n);
printf("%d\n",ans);
return 0;
}