Light Oj 1044 - Palindrome Partitioning(回文串)

http://lightoj.com/volume_showproblem.php?problem=1044

1044 - Palindrome Partitioning

A palindrome partition is the partitioning of a string such that each separate substring is a palindrome.

For example, the string "ABACABA" could be partitioned in several different ways, such as {"A","B","A","C","A","B","A"}, {"A","BACAB","A"}, {"ABA","C","ABA"}, or {"ABACABA"}, among others.

You are given a string s. Return the minimum possible number of substrings in a palindrome partition of s.

Input

Input starts with an integer T (≤ 40), denoting the number of test cases.

Each case begins with a non-empty string s of uppercase letters with length no more than 1000.

Output

For each case of input you have to print the case number and the desired result.

Sample Input

Output for Sample Input

3

AAAA

ABCDEFGH

QWERTYTREWQWERT

Case 1: 1

Case 2: 8

Case 3: 5


题意:把字符串分成回文串,求最少能分成几个字符串

思路:刚开始想到从第i个字符串往前判断有多少个回文串,但是时间复杂度为O(n^3),优化一下,遍历真个字符串,判断lr之间有多少个字符串,然后dp就ok了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
#include <algorithm>

using namespace std;

#define N 1010
#define INF 0x3f3f3f3f
#define MOD 2009
#define met(a, b) memset (a, b, sizeof(a))

typedef long long LL;

int vis[N][N];

int main ()
{
    int n, dp[N], nCase = 1;
    char str[N];
    scanf ("%d", &n);

    while (n--)
    {
        met (str, 0);
        met (vis, 0);
        scanf ("%s", str+1);

        for (int i=0; i<=N; i++)
            dp[i] = INF;

        dp[0] = 0;
        int len = strlen (str+1);

        for (int i=1; i<=len; i++)
        {
            for (int l=1; l+i-1<=len; l++)
            {
                int r = l+i-1;
                if (str[l] == str[r])
                {
                    if (l+1 > r-1)
                        vis[l][r] = 1;
                    else vis[l][r] = vis[l+1][r-1];
                }
            }
        }

        for (int i=1; i<=len; i++)
        {
            dp[i] = dp[i-1] + 1;
            for (int j=i-1; j>=1; j--)
            {
                if (vis[j][i])
                    dp[i] = min (dp[i], dp[j-1]+1);
            }
        }

        printf ("Case %d: %d\n", nCase++, dp[len]);
    }
    return 0;
}


你可能感兴趣的:(Light Oj 1044 - Palindrome Partitioning(回文串))