This is a dp problem where kmp algorithm(specially prefix function) is used to solve the problem.
If a string is multiple of a repeated string then the difference between the string length and last index of the prefix table indicates the minimal length of the repeated string. A brief and nice discussion is available here .
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#define INF 100000000
using namespace std;
int dp[85][85];
int lps[85];
string s;
int prefix_function(string str)
{
memset(lps,0,sizeof(lps));
int len = 0;
int i=1;
lps[0]=0;
int length = str.size();
while(i<length)
{
if(str[i]==str[len])
{
len+=1;
lps[i]=len;
i+=1;
}
else
{
if(len!=0)
{
len = lps[len-1];
}
else
{
len = 0;
i+=1;
}
}
}
int minimal_lengthOf_repeated_str = str.size()-lps[str.size()-1];
int times = str.size()/minimal_lengthOf_repeated_str;
if(str.size()==times*minimal_lengthOf_repeated_str)
return minimal_lengthOf_repeated_str;
else
return str.size();
}
int DP(int left,int right)
{
if(left==right)
return 1;
if(dp[left][right]!=-1)
return dp[left][right];
string str1 = s.substr(left,right-left+1);
int val = prefix_function(str1);
int ans1,ans2;
if(val==right-left+1)
{
int mn = INF;
for(int i=left;i<right;i++)
{
ans1 = DP(left,i);
ans2 = DP(i+1,right);
mn = (mn<(ans1+ans2)?mn:(ans1+ans2));
}
dp[left][right]=mn;
}
else
{
dp[left][right] = DP(left,left+val-1);
}
return dp[left][right];
}
int main()
{
while(cin>>s)
{
if(s=="*")
break;
memset(dp,-1,sizeof(dp));
printf("%d\n",DP(0,s.size()-1));
}
return 0;
}