Chef's Girl Friend has given him a unique gift. She has given him a string S. Chef being a gentleman wants to return her gift in a unique way. He wants to break the string he has received into some number of substrings so that each substring is a palindrome. However he does not want break the string into too many substrings, otherwise the average size of his strings will become small. What is the minimum number of substrings in which the given string can be broken so that each substring is a palindrome.
Tips:
Refer http://en.wikipedia.org/wiki/Palindrome for the definition of a "palindrome"
Input
Input description.
- The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows:
- The first line of each test case contains a single integer N denoting the number of alphabets in the given string. The second line contains the given string.
Output
For each test case output a single integer the answer to the given test case. Print answer for each test case on a separate line.
Constraints
All characters in the given string are upper case English alphabets.
- 1 ≤ T ≤ 10
- 1 ≤ |S| ≤ 5000
Example
Input:1 7 ABCCBDA
Output: 4
Explanation
Example case 1. The given string can be broken into "A" , "BCCB" , "D" , "A". It can be verified that you can't break the given string into less than 4 substrings such that each substring in a palindrome.
Scoring
Subtask 1: (15 points):
- 1 ≤ |S| ≤ 20
Subtask 2: (25 points):
- 1 ≤ |S| ≤ 250
Subtask 1: (60 points):
- 1 ≤ |S| ≤ 5000
思路:预处理每个回文串的位置,dp一下即可。
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
char s[5003];
int dp[5003];
vector<int>g[5003];
int main()
{
int t, n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
scanf("%s",s+1);
memset(dp, 0x3f, sizeof(dp));
dp[0] = 0;
for(int i=1; i<=n; ++i) g[i].clear();
for(int i=1; i<=n; ++i)
{
int j=i, k=i;
for(; j>0&&k<=n; --j,++k)
{
if(s[j]!=s[k]) break;
g[k].emplace_back(j);
}
}
for(int i=1; i<n; ++i)
{
if(s[i] != s[i+1]) continue;
int j=i, k=i+1;
for(; j>0&&k<=n; --j,++k)
{
if(s[j]!=s[k]) break;
g[k].emplace_back(j);
}
}
for(int i=1; i<=n; ++i)
for(auto j : g[i])
dp[i] = min(dp[i], dp[j-1]+1);
printf("%d\n",dp[n]);
}
return 0;
}