题意:给你一个字符串,每次可以一次性删去一个间断的回文串,问最少需要多少次能把字符串删完。
思路:状态压缩dp
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
const int maxn=1<<17;
int T,n;
string s;
int dp[maxn];
bool f[maxn];
//构造所有回文子串
void work1()
{
bool flag;
int sum;
char ss[20];
memset(f,0,sizeof(f));
for(int i=1;i<(1<<n);i++)
{
sum=0;
flag=1;
for(int j=1;j<=n;j++)
if((1<<(j-1))&i)
{
sum++;
ss[sum]=s[j-1];
}
for(int j=1;j<=sum;j++)
if(ss[j]!=ss[sum-j+1])
{
flag=0;
break;
}
f[i]=flag;
}
}
//DP
void work2()
{
for(int i=1;i<1<<n;i++)
dp[i]=100;
dp[0]=0;
for(int i=1;i<1<<n;i++)
for(int j=i;j;j=(j-1)&i)
if(f[j] && dp[i]>dp[i^j]+1)
dp[i]=dp[i^j]+1;
}
int main()
{
cin>>T;
while(T--)
{
cin>>s;
n=s.length();
work1();
work2();
cout<<dp[(1<<n)-1]<<endl;
}
return 0;
}