题目链接:BZOJ 1090
dp[i][j]表示区间[i,j]的最短折叠长度
转移方程为:dp[i][j]=min(j-i+1,dp[i][k]+dp[k+1][j])
特别地若满足区间[k+1,j]可以由区间[i,k]多次折叠得到,那么
dp[i][j]=min(dp[i][j],dp[i][k]+2+get((j-k)/(k-i+1)+1))//get函数是求一个数的位数
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char s[110];
int dp[110][110];
int wei(int x){
int tot=0;
while(x){tot++; x/=10;}
return tot;
}
bool jud(int a,int b,int c,int d){
int t=0;
for(int i=c;i<=d;i++){
if(s[i]!=s[a+t])return false;
t++;
if(t==b-a+1)t=0;
}
if(t!=0)return false;
else return true;
}
int get(int l,int r){
if(l==r)return 1;
if(dp[l][r])return dp[l][r];
int t=r-l+1;
for(int i=l;i<r;i++){
t=min(t,get(l,i)+get(i+1,r));
if(jud(l,i,i+1,r)){
t=min(t,get(l,i)+2+wei((r-i)/(i-l+1)+1));
}
}
return dp[l][r]=t;
}
int main(){
scanf("%s",s);
int l=strlen(s);
for(int i=l;i>=1;i--)s[i]=s[i-1];
printf("%d\n",get(1,l));
return 0;
}