Partitioning by Palindromes
We say a sequence of characters is a palindrome if it is the same written forwards and backwards. For example,‘racecar’ is a palindrome, but‘fastcar’ is not.
A partition of a sequence of characters is a list of one or more disjoint non-empty groups of consecutive characters whose concatenation yields the initial sequence. For example, (‘race’,‘car’) is a partition of ‘racecar’ into two groups.
Given a sequence of characters, we can always create a partition of these characters such that each group in the partition is a palindrome! Given this observation it is natural to ask: what is the minimum number of groups needed for a given string such that every group is a palindrome?
题目的意思就是输入一个由小写字母组成的字符串,我们需要把他们分成尽量小的回文创,不难推出dp方程为d[ i ] = min ( d[ j ]+1,d[ i ] ),剩下的难点就是时间,这里用的方法是先字符串可以成回文的地方判断一边,做一下标记,然后再用dp来做。
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
bool pd[1010][1010];
int l,dp[1010];
char s[1010];
void init()
{
for(int i=0;i<=l;i++) {pd[i][i]=1;dp[i]=i;} //初始化,最差的情况是没有回文,各字母为1
for(int i=1;i<=l;i++) //判断字符串i~j是回文然后用pd[][]标记
{
int j=1;
while(i-j>=0&&i+j<=l)
{
if(s[i-j+1]==s[i+j]) { pd[i-j+1][i+j]=1;j++;}
else break;
}
j=1;
while(i-j>=1&&i+j<=l)
{
if(s[i+j]==s[i-j]) { pd[i-j][i+j]=1;j++;}
else break;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(pd,0,sizeof(pd));
memset(s,0,sizeof(s));
scanf("%s",s+1);
l=strlen(s+1);
init();
for(int i=1;i<=l;i++){ //dp过程
for(int j=1;j<=i;j++){
if(pd[j][i]) dp[i]=min(dp[i],dp[j-1]+1);
}
}
printf("%d\n",dp[l]);
}
return 0;
}