Description
You heart broke into pieces.My string broke into pieces.But you will recover one day,and my string will never go back.
Given a string s.We can erase a subsequence of it if this subsequence is palindrome in one step. We should take as few steps as possible to erase the whole sequence.How many steps do we need?
For example, we can erase abcba from axbyczbea and get xyze in one step.
Given a string s.We can erase a subsequence of it if this subsequence is palindrome in one step. We should take as few steps as possible to erase the whole sequence.How many steps do we need?
For example, we can erase abcba from axbyczbea and get xyze in one step.
Input
The first line contains integer T,denote the number of the test cases. Then T lines follows,each line contains the string s (1<= length of s <= 16).
T<=10.
T<=10.
Output
For each test cases,print the answer in a line.
Sample Input
2 aa abb
Sample Output
1 2
题目大意:
给一个字符串,每次可以删除一个可不连续回文子串,问最少删几次可以全部删完。
思路:
因为字符串长度最大16,所以可用二进制状态表示, 1表示选取这个字符,0不选,组成一个子串。
先预处理出所有状态,看这个状态是不是回文。
状压的循环过程需要技巧。。。预处理也是一个需要思考的环节
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int N = 17;
const int inf = 0x3f3f3f3f;
int dp[1<<N];
vector<int>G[1<<N];
char str[N];
int judge(int n);
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%s",str);
int n=strlen(str);
for(int i=1;i<(1<<n);i++)
{
if(judge(i)) dp[i]=1;
else dp[i]=inf;
}
dp[0]=0;
for(int i=1;i<(1<<n);i++)
{
for(int j=(i-1)&i;j;j=(j-1)&i)
dp[i]=min(dp[i],dp[j]+dp[i^j]);
}
printf("%d\n",dp[(1<<n)-1]);
}
return 0;
}
int judge(int n)
{
int len=G[n].size();
for(int i=0,j=len-1;i<j;i++,j--)
{
int x=G[n][i], y=G[n][j];
if(str[x]!=str[y])
return 0;
}
return 1;
}