集训第五周动态规划 H题 回文串统计

Hrdv is interested in a string,especially the palindrome string.So he wants some palindrome string.A sequence of characters is a palindrome if it is the same written forwards and backwards. For example, 'abeba' is a palindrome, but 'abcd' 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?For example:'racecar' is already a palindrome, therefore it can be partitioned into one group.'fastcar' does not contain any non-trivial palindromes, so it must be partitioned as ('f', 'a', 's', 't', 'c', 'a', 'r').'aaadbccb' can be partitioned as ('aaa', 'd', 'bccb').Input begins with the number n of test cases. Each test case consists of a single line of between 1 and 1000 lowercase letters, with no whitespace within.Each test case consists of a single line of between 1 and 1000 lowercase letters, with no whitespace within.For each test case, output a line containing the minimum number of groups required to partition the input into groups of palindromes

racecar

fastcar

aaadbccb

1

7

3

 

使用dp(i)表示从数组起始位置到i位置回文串的个数

动态规划方程为

dp(i)=min{dp(j-1)+1,dp[i]}  //if(子串j~i是回文串)

初始给dp赋值为一个大数,代表这个区间的回文串个数未知

#include"iostream"
#include"cstdio"
#include"cstring"
#include"algorithm"
using namespace std;
const int maxn=1010;
char aa[maxn];
int dp[maxn];

bool is_palindrome(int a,int b)
{
    int m=(a+b)>>1;
    for(int i=a; i<=m; i++)
        if(aa[i]!=aa[b-i+a]) return false;
    return true;
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
      scanf("%s",aa+1);
      int n=strlen(aa+1);
      memset(dp,0,sizeof(dp));
      dp[0]=0;
    for(int i=1;i<=n+1;i++) dp[i]=n;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=i;j++)
      {
        if(is_palindrome(j,i))
          //dp[i]=dp[j-1]+1;
            dp[i]=min(dp[i],dp[j-1]+1);
      }
      cout<<dp[n]<<endl;
    }
    return 0;
}
View Code

 

 

 

posted @ 2015-08-12 21:05  江南何采莲  阅读(222)  评论(0编辑  收藏  举报