题意:
给你一个字符串,每次删去一回文串,求最少需要多少次可以把串删完。。
比赛的时候没有学习状态压缩dp,最近刚学习,感觉还不错,就是位运算不是太熟练应用。。
首先先求出所有的回文状态,然后就可以按照转移方程计算就可以了
dp[i]=min(dp[i],dp[i-j]+1) j表示每次对i删去一个1得到的结果&&j必须也是回文的。。。
#include"stdio.h"
#include"string.h"
#define inf 20
int state[1<<16];
int dp[1<<16];
int min(int x,int y)
{
return x<y?x:y;
}
int main()
{
int T;
int n;
int cnt;
int i,j,k;
char s[16],ss[16];
scanf("%d",&T);
getchar();
while(T--)
{
gets(s);
n=strlen(s);
for(i=0;i<(1<<n);i++)
{
cnt=0;
for(j=0;j<n;j++)
{
if((i>>j)&1)ss[cnt++]=s[j];
}
state[i]=1;
for(j=0,k=cnt-1;j<k;j++,k--)
{
if(ss[j]!=ss[k])
{
state[i]=0;break;
}
}
}
dp[0]=0;
for(i=1;i<(1<<n);i++)
{
dp[i]=20;
for(j=i;j>0;(--j)&=i)
//注意这里的(--j)&=i,是对j每次删去一个最右边的1
{
if(state[j])
dp[i]=min(dp[i],dp[i-j]+1);
}
}
printf("%d\n",dp[(1<<n)-1]);
}
return 0;
}