We say a sequence of characters isa
A
Given a sequence of characters, we can alwayscreate a partition of these characters such that each group in thepartition is a palindrome! Given this observation it is natural toask: what is the minimum number of groups needed for a given stringsuch that every group is a palindrome?
For example:
- 'racecar' is already a palindrome, therefore it can bepartitioned into one group.
- 'fastcar' does not contain any non-trivial palindromes, so itmust be partitioned as ('f', 'a', 's', 't', 'c', 'a', 'r').
- 'aaadbccb' can be partitioned as ('aaa', 'd', 'bccb').
Input begins with thenumber
For each test case, output a line containing theminimum number of groups required to partition the input intogroups of palindromes.
Sample Input
3
racecar
fastcar
aaadbccb
Sample Output
1
7
3
经典DP,解法参照紫书,先用O(n2)的代价预处理字符串:re[i][j]表示从下标i到j的子串是否是回文串。dp[i]表示0~i能划分的最少回文串数,状态转移:dp[i]=min(dp[i],dp[j]+1),AC代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int maxn=1000+5;
const int INF=1<<30;
int dp[maxn];
bool re[maxn][maxn];
int main()
{
int n;
string a;
cin>>n;
while(n--)
{
memset(re,false,sizeof(re));
cin>>a;
int len=a.length();
dp[0]=0;
for(int i=1;i<=len;++i) dp[i]=INF;
for(int i=0;i<len;++i)
{
int l=i,r=i;
while(a[l]==a[r]&&l>=0&&r<len)
re[l+1][++r]=true,--l;
if(i+1<len)
{
l=i,r=i+1;
while(a[l]==a[r]&&l>=0&&r<len)
re[l+1][++r]=true,--l;
}
}
for(int i=1;i<=len;++i)
for(int j=0;j<i;++j)
if(re[j+1][i]) dp[i]=min(dp[i],dp[j]+1);
cout<<dp[len]<<endl;
}
}