UVa 11584 Partitioning by Palindromes

/*---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\n", dp[n]);
	}
	return 0;
}

  

posted @ 2016-08-20 21:26  曹孟德  阅读(148)  评论(0编辑  收藏  举报