Partitioning by Palindromes UVA - 11584 动态规划
题意是给定一个字符串,求最少把它分成多少份,使的每一份都是回文串。
错了好多遍,最后发现是贪心思路出了问题,一开始求出dp[i][j],dp[i][j]表示第i个到第j个这段子串是否是回文串,求出来后,我直接从1开始遍历,每次求最右边的,这种贪心思路是有问题的。
赛后看了别人的才知道可以用动态规划,dp1[i]表示从1到第i个最少分成多少份,知道这思路就可以直接写了。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <string> 6 #include <queue> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #define ll long long 11 #define INF 0x3f3f3f3f 12 #define lowvit(x) x&(-x) 13 #define N 1010 14 #define M 110 15 using namespace std; 16 char str[N]; 17 bool dp[N][N]; 18 int dp1[N]; 19 int main() { 20 int t; 21 cin>>t; 22 while(t--) { 23 memset(dp, 0, sizeof(dp)); 24 memset(str, 0, sizeof(str)); 25 memset(dp1, 0, sizeof(dp1)); 26 cin>>str+1; 27 int len = strlen(str+1); 28 for(int i = 1; i <= len; i ++) { 29 dp[i][i] = 1;dp1[i] = INF; 30 if(i+1 <= len && str[i] == str[i+1]) dp[i][i+1] = 1; 31 } 32 for(int i = 3; i <= len; i ++) { 33 for(int j = 1; j <= len-i+1; j ++) { 34 int r = j+i-1; 35 if(dp[j+1][r-1] && str[j] == str[r]) dp[j][r] = 1; 36 } 37 } 38 dp1[0] = 0; 39 for(int i = 1; i <= len; i ++) { 40 for(int j = 1; j <= len; j ++) { 41 if(dp[j][i]) { 42 dp1[i] = min(dp1[i],dp1[j-1]+1); 43 } 44 } 45 } 46 cout << dp1[len] << endl; 47 } 48 return 0; 49 }