uva 11584 Partitioning by Palindromes (动态规划)

来源:互联网 发布:汉宫外设淘宝店网址 编辑:程序博客网 时间:2024/05/16 04:45

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;}
原创粉丝点击