F[i][j]表示区间i到j的最短折叠
转移时枚举区间中的点即可
#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define T 50005
using namespace std;
char s[111];
int f[111][111],mark[111][111];
bool jud(int L,int x,int y,int R)
{
if((R-y+1)%(x-L+1)!=0)return 0;
for(int i=y;i<=R;i++)
{
if(s[i]!=s[(i-y)%(x-L+1)+L])
return 0;
}
return 1;
}
int cal(int x)
{
int ans=0;
for(;x;x/=10)ans++;
return ans;
}
int F(int L,int R)
{
if(L==R)return 1;
if(mark[L][R])return f[L][R];
mark[L][R]=1;
f[L][R]=R-L+1;
for(int i=L;i<R;i++)
{
f[L][R]=min(f[L][R],F(L,i)+F(i+1,R));
if(jud(L,i,i+1,R))
{
f[L][R]=min(f[L][R],F(L,i)+2+cal((R-i)/(i-L+1)+1));
}
}
//cout << L <<" "<<R<<" " <<f[L][R]<<endl;
return f[L][R];
}
int main()
{
scanf("%s",s);
cout<<F(0,strlen(s)-1);
return 0;
}