uva 11584 Partitioning by Palindromes (动态规划)

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

猜你喜欢

转载自blog.csdn.net/j1nab1n9/article/details/78069082