CodeChef:Girl Friend and String Gift(dp)

来源:互联网 发布:上古卷轴rm捏脸数据 编辑:程序博客网 时间:2024/06/10 14:24

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 7ABCCBDA
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;}