6.14-最少回文串划分-dp

给一个字符串, 要求把它分割成若干个子串,使得每个子串都是回文串。问最少可以分割成多少个。

#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;  
    }  
}  

猜你喜欢

转载自blog.csdn.net/cd651/article/details/80694165