Uva 11584 dp分割最少回文串
传送门:https://vjudge.net/problem/UVA-11584
给一个字符串, 要求把它分割成若干个子串,使得每个子串都是回文串。问最少可以分割成多少个。
f[i]表示以i结尾的串最少可以分割的串数。
f[i] = min{ f[j]+1, 串[j,i]是回文串&&1<=j<=i }
处理好边界,我这里直接以字符串0开始,初始化每个dp[i]最大 = i+1,假定都不能分割。当从0开始到当前i是回文串,则直接赋值1,此时dp[j-1]是不存在的。
遍历以i结尾的所有后缀串,若从j开始到i是回文串,则=min(dp[i],dp[j-1]+1),以此来转移状态,压缩确定最少分割数。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int MAXN = 1010; char str[MAXN]; int f[MAXN]; bool isPalind(int l, int r){ while(l<r){ if(str[l] != str[r]) return false; ++l; --r; } return true; } int main(){ // freopen("in.txt","r",stdin); int T; scanf("%d", &T); while(T--){ scanf("%s", str); int len = strlen(str); memset(f, 1, sizeof(f)); for(int i = 1; i < len; i++){ f[i] = i+1; for(int j=0; j<=i; j++) //遍历以i结尾的每个串 //如果是回文串,则以j为开头到i的串+1跟当前比较 if(isPalind(j, i)){ if(j==0) { f[i] = min(f[i], 1); } else { f[i] = min(f[i], f[j-1]+1); } } } printf("%d\n", f[len-1]); } return 0; }