本来想发博客的,结果自己过不了就很尴尬
#include<bits/stdc++.h>
using namespace std;
int k,dp[110][110],m[110];
char a[100];
bool check(char a[],int n,int len){
for(int i=len;i<n;i++)
if(a[i]!=a[i%len]) return false;
return true;
}
int main()
{
int len,i,j,l;
/*do{
cin>>a[k];
k++;
}while(a[k]!='\n');
k--;*/
//也可以这样输入(高级)
scanf("%s",a);
k=strlen(a);
for(i=1;i<=9;i++) m[i]=1;
for(i=10;i<=99;i++) m[i]=2;
m[100]=3;//根据数字位数赋初值
memset(dp,0x3f,sizeof(dp));//dp[i][j]代表字符串i到j这段最小的长度,初始为无穷大
for(i=1;i<=k;i++) dp[i][i]=1;//i,i为1
for(int op=2;op<=k;op++)//代表当前判断的这段的长度
{
for(i=0,j=i;j<=i+op-1;i++,j++)//i为左端点,j为右端点,长度为op,所以j<=i+op-1;一次循环做完就使左端点和右端点都右移一位,即i++,j++
{
for(l=i;l<j;l++)
dp[i][j]=min(dp[i][j],dp[i][l]+dp[l+1][j]);//分成i-l,和l+1-j
for(l=i;l<j;l++)//个人感觉可以变成l<=mid,mid=i+j>>1,因为至少分为2段
{
len=l-i+1;//代表要判断的这段的长度
if(op%len!=0) continue;//op%len!=0说明不能将i,j分为op/len段 进行下一次循环
if(check(a+i,op,len)) dp[i][j]=min(dp[i][j],dp[i][l]+2+m[op/len]);//dp[i][k]是折叠的一段,2是括号,m[op/len]是数字占的位数
}
}
}
cout<<dp[0][k-1]<<"\n";
return 0;
}