链接:点击打开链接
题意:给出一个字符串,每次删除一个回文子序列,问最少删除多少次才能给这个字符串全部删完
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
char s[20];
int dp[(1<<16)+5],sign[(1<<16)+5];
int judge(int x){
int l,r,len;
len=strlen(s);
l=0,r=len-1;
while(l<r){
while(!(x&(1<<l)))
l++;
while(!(x&(1<<r)))
r--;
if(s[l]!=s[r])
return 0;
l++,r--;
}
return 1;
} //判断每个状态是否回文
int main(){ //dp[s]表示状态是s时最少删除的次数
int t,i,j,len; //dp[s]=min(dp[s],dp[s-tmp]+1),tmp为s
scanf("%d",&t); //的一个子状态并且是回文子序列
while(t--){
scanf("%s",s);
len=strlen(s);
memset(dp,INF,sizeof(dp));
memset(sign,0,sizeof(sign));
dp[0]=0;
for(i=1;i<(1<<len);i++)
if(judge(i)) //预处理出哪些状态是回文
sign[i]=1;
for(i=0;i<(1<<len);i++){
for(j=i;j>0;j=i&(j-1)){ //枚举每个i的子状态
if(sign[j])
dp[i]=min(dp[i],dp[i-j]+1);
}
}
printf("%d\n",dp[(1<<len)-1]);
}
return 0;
}