UVA - 11584 Partitioning by Palindromes

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34398

题意:给你一个长度为n(n<1000)的字符串,问你最小可以拆分成多少个回文串。

解法:我们可以设d[i]为从0个开始到i个字目可以组成多少个回文串,则d[0]=0,没有字母时回文串为0个。d[i]=min(d[i],d[j]+1) 从第j+1个到第i个是回文串。然后我们就可以由边界推到答案了。

对于回文串的预处理:我们可以用s[i][j]表示i第i个到第j个是回文串。我们可以从枚举中心,然后判断它的左右字符。这里有个值得注意的是,中心可能没有字符。

#include <algorithm>
#include <string>
#include <iostream>
#include <string.h>
#include<stdio.h>
#include<math.h>
#include<vector>
using namespace std;
#define ll  long long int
const ll  mod=1000000007;
const int inf=1e9;
const int maxn = 1000;
bool h[maxn+10][maxn +10];
char s[maxn+10];
int d[maxn+10];


int main()
{
   int n ;
   scanf("%d",&n);
   while(n--)
   {
       scanf("%s",s);
       memset(h,0,sizeof h);
       for(int i=0;i<=maxn;i++) d[i]=inf;
       d[0]=0;
       for(int t=0;t<strlen(s);t++)
       {
           int st,ed;
           st=ed=t;//中心有字符
           while(st>=0&&ed<strlen(s))
           {
               if(s[st]==s[ed])
               {
                   h[st][ed]=1;
                   st--;
                   ed++;
               }
               else break;
           }
            st=t,ed=t+1;//如果中心没有字符
            while(st>=0&&ed<strlen(s))
           {
               if(s[st]==s[ed])
               {
                   h[st][ed]=1;
                   st--;
                   ed++;
               }
               else break;
           }


       }
       for(int i=1;i<=strlen(s);i++)
       {
           for(int j=0;j<i;j++)
           {
               if(h[j][i-1]==1)
               {


                   d[i]=min(d[i],d[j]+1);
                   //cout<<d[i]<<endl;
               }
           }
       }
       printf("%d\n",d[strlen(s)]);//显示答案


   }


     return 0;
}

你可能感兴趣的:(dp,uva)