給一個字符串, 要求把它分割成若干個子串,使得每個子串都是迴文串。問最少可以分割成多少個。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
char str[1010];
int dp[1010];
bool check(int l,int r)
{
for(int i=l,j=r;i<=j;i++,j--)
{
if(str[l]!=str[r])
{
return false;
}
return true;
}
}
int main()
{
int t;
cin>>t;
for(int i=1;i<=t;i++)
{
scanf("%s",str+1);//這個地方從1開始是爲了後面的方便
int len=strlen(str+1);
for(int j=1;j<=len;j++)
{
dp[j]=INF;
}
dp[0]=0;
for(int ii=1;ii<=len;ii++)
{
for(int jj=ii;jj>=1;jj--)
{
if(check(jj,ii)==true)
{
dp[ii]=min(dp[jj-1]+1,dp[ii]);
}
}
}
printf("%d\n",dp[len]);
}
}
對於迴文串的判斷,也可以直接dp:
void pre()
{
/*令flag[i][j]=1表示長度爲i從str的第j個位置開始有一回文串,
否則flag[i][j]=0*/
memset(flag,0,sizeof(flag));
for(int i=1;i<=l;i++)flag[1][i]=1;
if(l==1)return;
for(int i=1;i<=l-1;i++)if(str[i]==str[i+1])flag[2][i]=1;
for(int i=3;i<=l;i++)
for(int j=1;j<=l-i+1;j++)
{
/*j開始i的長度是迴文詞是加上從j+1開始i-2的長度
是迴文詞切加上兩邊構成新的迴文詞 */
if(flag[i-2][j+1] && str[j]==str[j+i-1])
flag[i][j]=1;
}
}