每次可以去掉一个回文串,求最少几步能取完。
两种做法,一种是dp,一种是记忆化搜索。分别附上代码。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define Maxn 1<<17
#define Inf 1<<17
int hash[Maxn],slen;
char s[17];
int Judge(int n)
{
char ts[17];
int cnt=0,i;
for(i=0;i<slen && n;i++)
{
if(n&1) ts[cnt++]=s[i];
n>>=1;
}
ts[cnt]='\0';
for(i=0;i<cnt/2;i++)
if(ts[i]!=ts[cnt-i-1]) return 0;
return 1;
}
int main()
{
int T,i,j;
int dp[Maxn];
scanf("%d",&T);
while(T--){
memset(hash,0,sizeof(hash));
memset(dp,0,sizeof(dp));
scanf("%s",&s);
slen=strlen(s);
int n=1<<slen;
for(i=1;i<n;i++)
if(Judge(i)) //状态压缩,求出所有的回文子串
hash[i]=1;
dp[0]=0;
for(i=n-2;i>=0;i--){ //层层求最少,dp[0]即为结果
dp[i]=Inf;
for(j=i+1;j<n;j=(j|i)+1)
if(hash[j-i])
dp[i]=min(dp[i],dp[j]+1);
}
printf("%d\n",dp[0]);
}
return 0;
}