UVA 11584 Partitioning by Palindromes(메모 DP, 레벨 4)

2822 단어
A - Partitioning by Palindromes
Crawling in process...
Crawling failed
Time Limit:1000MS    Memory Limit:0KB     64bit IO Format:%lld & %llu
Submit
Status
Appoint description: System Crawler (2013-05-30)
Description

Problem H: 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?
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.
    For each test case, output a line containing the minimum number of groups required to partition the input into groups of palindromes.

    Sample Input

    3
    racecar
    fastcar
    aaadbccb
    

    Sample Output

    1
    7
    3
    

    Kevin Waugh
     
    한 꿰미는 적어도 몇 개의 회문 꿰미로 나누어야 한다
    사고방식: 먼저 회문열을 표시한 다음DP를 한 번 훑어본다.
       
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #define FOR(i,a,b) for(int i=a;i<=b;++i)
    #define clr(f,z) memset(f,z,sizeof(f))
    using namespace std;
    const int mm=1009;
    char s[mm];
    bool isp[mm][mm];
    int dp[mm];
    int main()
    {
      int cas;
      while(~scanf("%d",&cas))
      {
        while(cas--)
        { clr(isp,0);
          scanf("%s",s);
          int len=strlen(s);
          FOR(i,0,len)isp[i+1][i]=isp[i+2][i]=1;
          for(int i=len;i>0;--i)
            FOR(j,i,len)
            if(isp[i+1][j-1]&&s[i-1]==s[j-1])isp[i][j]=true;
          dp[0]=0;
          FOR(i,1,len)
          {
            dp[i]=mm;
            FOR(j,1,i)
            if(isp[j][i])
              dp[i]=min(dp[i],dp[j-1]+1);
          }
          printf("%d
    ",dp[len]); } } return 0; }

    좋은 웹페이지 즐겨찾기