lightoj 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

 

这题的大意是给你一个字符串,让你把他分割成每一段都是回文,问你分成最少的子串数是多少。

这题可以用类似区间DP的处理方法把每一个段是不是回文处理出来,然后DP就好了。

dp[i]表示处理到第i个字符的时候子串数量,如果j到i这一段是回文的话,那么状态转移方程就是这个dp[i] = min(dp[i],dp[j-1]+1)。

虽然每一次都暴力判断这一段是不是回文也可以过,但是感觉这样逼格高一点。


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

using namespace std;
const int inf = 1e9;
int judge[1100][1100];
int dp[1100];
char a[1100];
int main(void)
{
    int T,n,i,j,l;
    scanf("%d",&T);
    int c = 1;
    while(T--)
    {
        scanf("%s",a+1);
        n = strlen(a+1);
        memset(judge,0,sizeof(judge));
        for(l=1;l<=n;l++)
        {
            for(i=1;l+i-1<=n;i++)
            {
                j = l+i-1;
                if(a[i] == a[j])
                    judge[i][j]=i+1>j-1?1:judge[i+1][j-1];
                else
                    judge[i][j] = 0;
            }
        }
        for(i=1;i<=n;i++)
        {
            dp[i] = inf;
            for(j=1;j<=i;j++)
                if(judge[j][i])
                {
                    if(j == 1)
                        dp[i] = 1;
                    else
                        dp[i] = min(dp[i],dp[j-1] + 1);
                }
        }
        printf("Case %d: %d\n",c++,dp[n]);
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值