题意:输入一个由小写字母组成的字符串,你的任务是把它划分成尽量少的回文串。
题解:d(i)为字符0~i划分成的最小回文串的个数,则d[ i ]=min{ d[ j ]+1 |s[ j+1~ i ]是回文串 }。
注意要预处理,其次是怎么初始化。。。很重要
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define INF 1e8 6 using namespace std; 7 8 const int maxn=1005; 9 10 int len; 11 int dp[maxn]; 12 char s[maxn]; 13 bool vis[maxn][maxn]; 14 15 void init(){ 16 memset(vis,false,sizeof(vis)); 17 for(int i=0;i<len;i++){ 18 int k1=i,k2=i; 19 while(0<=k1&&k2<len&&s[k1]==s[k2]) { vis[k1][k2]=true; k1--,k2++; } 20 k1=i,k2=i+1; 21 while(0<=k1&&k2<len&&s[k1]==s[k2]) { vis[k1][k2]=true; k1--,k2++; } 22 } 23 } 24 25 void solve() 26 { init(); 27 for(int i=1;i<len;i++){ 28 if(vis[0][i]) dp[i]=1; 29 for(int j=0;j<i;j++) 30 if(vis[j+1][i]) dp[i]=min(dp[i],dp[j]+1); 31 } 32 int ans=dp[len-1]; 33 cout<<ans<<endl; 34 35 } 36 37 int main() 38 { int kase; 39 cin>>kase; 40 while(kase--){ 41 scanf("%s",s); 42 len=strlen(s); 43 for(int i=0;i<len;i++) dp[i]=i+1; 44 45 solve(); 46 } 47 return 0; 48 }