4月事情有点多,没怎么写,这个月要抓紧了.
思路:
用动态规划判断会问串:d[i][j] 代表从位置j开始的长度为i的是否为回文串;
容易得到 if(ck[i-2][j+1]&&c[j]==c[j+i-1]) ck[i][j]=1;
注意要先算所有同一长度的 所以
for(int i=3;i<=n;++i)
for(int j=1;j<=n-i+1;++j)
第二个方程:if(ck[j][i-j+1]) f[i]=min(f[i],f[i-j]+1);
Code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e3+10;
char c[N];
int f[N],n;
bool ck[N][N];
void pre(){
memset(ck,0,sizeof(ck));
fo(i,1,n) ck[1][i]=1;
fo(i,1,n-1) if(c[i]==c[i+1]) ck[2][i]=1;
for(int i=3;i<=n;++i)
for(int j=1;j<=n-i+1;++j){
if(ck[i-2][j+1]&&c[j]==c[j+i-1]) ck[i][j]=1;
}
}
int main(){
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",c+1);
n=strlen(c+1);
pre();
memset(f,63,sizeof(f));
f[0]=0;
fo(i,1,n)
fo(j,1,i)
if(ck[j][i-j+1]) f[i]=min(f[i],f[i-j]+1);
printf("%d\n",f[n]);
}
}