题意
当一个字符串正序和反序是完全相同时,我们称之为“回文串”。例如“racecar”就是一个回文串,而“fastcar”就不是。现在给一个字符串s,把它分割成若干个互不相交的回文子串,求分割的回文子串的最少个数。
分析
CODE
scanf("%s", s + 1);//下面要用到字符的第一位跟前一位比较,从1开始方便初始化,c++没有负数数组。
s[0] = '0';//填上第一位,如果不填strlen算出长度就是0
int len = strlen(s)-1;
memset(sum,0,sizeof(sum));//多组数据要初始化。
//求sum有三种情况
for(int i=1; i <= len; i++)
{
int j,k;
sum[i][i]=1;//每个单独的字符是回文串
for(j =i, k = i+1 ; j >= 1 && k <= len ; j--, k++)
{//如果是偶数个的回文串
if(s[j] == s[k] )
{
if(j+1<=k-1 && sum[j+1][k-1])//不能j+1,k-1后j跑到k前面去了
sum[j][k]=1;
if(k-j==1)//如果只相差1就是两个相邻的字符
sum[j][k]=1;
}
//if(sum[j][k]) cout<<j<<"->"<<k<<" "<<sum[j][k]<<endl;
}
for(j = k = i ; j >= 1 && k <= len ; j--, k++)
{//如果是奇数的回文串
if(s[j] == s[k] &&k!=j && sum[j+1][k-1])
{
sum[j][k]=1;
}
//if(sum[j][k]) cout<<j<<"->"<<k<<" "<<sum[j][k]<<endl;
}
}
memset(f,12,sizeof(f));//初始化为无穷大
f[0]=0;//方便更新状态
for(int i=1;i<=len;i++)
{
for(int j=1;j<=i;j++)
if(sum[j][i])f[i]=min(f[i],f[j-1]+1);
}
cout<<f[len]<<endl;;