Partitioning by Palindromes UVA

来源:互联网 发布:店帮帮软件用途 编辑:程序博客网 时间:2024/06/04 08:10

点下看看能不能打开:https://vjudge.net/problem/34398/origin

题目大意:输入小写字母字符串,然后分割成尽量少的回文串,例如:recacer本身就是回文串,fastcar只能分成7个,aaadbccb最少为3个为:aaa   d  bccb

ps:紫书p275 

ps:记得以前做过关于回文串的dp,那个是比较复杂的了,属于区间dp的。

对于这个题的话,要求最少的回文串,那么就记录dp[j]表示前j个字符所能分割的最少回文串。那么如果出现i在j的后面,如果j+1~i是回文的话,那么就要比较dp[i]和dp[j]+1的大小去min;j是从0-i的

这里有一个预处理求区间[i,j]是否回文串的,详细见代码。为了方便处理,字符串从1开始的。

#include <iostream>#include <bits/stdc++.h>#define INF 0x3f3f3f3fusing namespace std;char s[1111];int dp[1111];int vis[1111][1111];int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%s",s+1);        int n=strlen(s+1);        memset(vis,0,sizeof(vis));        memset(dp,INF,sizeof(dp));///最大化        for(int k=1;k<=n;k++)        {            int i,j;            i=k;            j=k;            while(i>0&&j<=n)            {                if(s[i]==s[j])                {                    vis[i][j]=1;                    i--;                    j++;                }                else break;            }            i=k;            j=k+1;            while(i>0&&j<=n)            {                if(s[i]==s[j])                {                    vis[i][j]=1;                    i--;                    j++;                }                else break;            }        }        dp[0]=0;        for(int i=1;i<=n;i++)        {            for(int j=0;j<i;j++)            {                if(vis[j+1][i])                {                    dp[i]=min(dp[i],dp[j]+1);                }            }        }        printf("%d\n",dp[n]);    }    return 0;}


0 0
原创粉丝点击