/*---UVa 11584 Partitioning by Palindromes --用dp[i]表示前i个字母划分成最小回文串的个数,则有dp[i]=min{dp[j]+1}s[j+1...i]是一个回文串,状态O(n)个 每次有O(n)个决策,而判断是否是回文串复杂度O(n),这样总的复杂度O(n^3).如果事先预处理标记一下s[i...j]是否构成 回文串,这样总的复杂度O(n^2)。标记s[i...j]是否构成回文串,用vis[i][j](i<=j)来标记,if s[i]!=s[j]则vis[i][j]=0 if s[i]==s[j],则vis[i][j]=vis[i+1][j-1]; */ #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<vector> #include<string.h> #include<math.h> #include<algorithm> #define INF 0x3f3f3f3f using namespace std; const int maxn = 1000+10; char str[maxn]; int dp[maxn], vis[maxn][maxn]; //记忆化搜索 int dfs(int i, int j){ int &ans = vis[i][j]; if (ans >=0)return ans; //以计算过 if (i >= j) return ans=1; //边界 if (str[i] != str[j])return ans = 0; return ans = dfs(i + 1,j - 1); } int main(){ int t,n, i,j; scanf("%d", &t); while (t--){ scanf("%s",str+1); n = strlen(str+1); memset(vis, -1, sizeof(vis)); for (i = 1; i <=n; i++){ for (j = 1; j <= i; j++) vis[j][i]=dfs(j, i); } dp[0] = 0; //第一个 for (i = 1; i <=n; i++){ dp[i] = INF; for (j = 1; j <= i; j++){ if (vis[j][i]) dp[i] = min(dp[i], dp[j - 1] + 1); } } printf("%d ", dp[n]); } return 0; }