1、UVa 11584 Partitioning by Palindromes(字符串区间dp)
题意:给出一个字符串,划分为若干字串,保证每个字串都是回文串,同时划分数目最小。
思路:dp[i]表示以第i位结尾时最小的划分数目(初始均为0)
状态转移方程1:(初始均为0)当[j:i]是回文串(0≤j≤i,0≤i<n):dp[i]=1(j==0);dp[i]=(dp[i]==0?dp[j-1]+1:min(dp[i],dp[j-1]+1))
状态转移方程2:(初始:dp[i]=i+1)当[j:i]是回文串(0≤j≤i,0≤i<n):dp[i]=1(j==0);dp[i]=min(dp[i],dp[j-1]+1))
状态转移方程3:(初始:dp[i]=i+1(1≤i≤n);其他:dp[i]=0)当[j:i]是回文串(1≤j≤i,1≤i≤n):dp[i]=min(dp[i],dp[j-1]+1))
1 #include<iostream> 2 #include<memory.h> 3 #include<string.h> 4 #include<algorithm> 5 #include<cstdio> 6 using namespace std; 7 const int maxn = 1005; 8 char s[maxn]; 9 int dp[maxn]; 10 int n; 11 bool Judge(int st, int ed) 12 { 13 for (; st <= ed; st++, ed--) 14 { 15 if (s[st] != s[ed]) return false; 16 } 17 return true; 18 } 19 int main() 20 { 21 cin >> n; 22 while (n--) 23 { 24 scanf("%s", s); 25 memset(dp, 0, sizeof(dp)); 26 int sz = strlen(s); 27 for (int i = 0; i < sz; i++) 28 { 29 for (int j = 0; j <= i; j++) 30 { 31 if (Judge(j, i)) 32 { 33 if (j == 0) dp[i] = 1; 34 else dp[i] = dp[i] == 0 ? dp[j - 1] + 1 : min(dp[i], dp[j - 1] + 1); 35 } 36 } 37 } 38 cout << dp[sz - 1] << endl; 39 } 40 return 0; 41 }