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]);
}
}