标签:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; char a[4200]; int dp[4200]; int b[4200][4200]; int path[4200]; int n; char pri[4200][4200]; void inti(){ for(int i = 1 ; i <= n; i++){ for(int j = i + 1 ;j <= n; j++){ int k,p; for( k = i,p = j; k < p; k++,p--){ if(a[k] != a[p] ) break; } if(k >= p) b[i][j] = j - i + 1; } } for(int i = 1 ; i <= n; i++) b[i][i] = 1; } int main() { while(~scanf("%s",a+1)){ memset(b,0,sizeof(b)); memset(dp,0,sizeof(dp)); memset(path,0,sizeof(path)); n = strlen(a+1); inti(); dp[1] = 1; for(int i = 2 ; i <= n;i++) dp[i] = dp[i-1]+1; dp[0] = 0; for(int i = 1; i <= n; i++){ for(int j = i ; j <= n; j++){ if(dp[j-b[i][j]]+1 <= dp[j]){ dp[j] = dp[j-b[i][j]] + 1; path[j] = j - b[i][j]; } } } //for(int i = 1; i <= n ;i++) //printf("%d\n",path[i]); // for(int i = 1; i <= n; i++) // for(int j = i+1 ; j <= n;j++) // printf("%d ",b[i][j]); // for(int i = 1 ; i <= n; i++) // printf("%d ",dp[i]); printf("%d\n",dp[n]); int i = n ; int t1 = 1; int t2; memset(pri,0,sizeof(pri)); while( i >= 1){ t2 = 1; for(int j = path[i]+1; j <= i ;j++){ pri[t1][t2++] = a[j]; // printf("%d%d%c ",t1,t2-1,pri[t1][t2-1]); } // printf("\n"); t1++; i = path[i]; } // printf("%d",t1); for(int i = t1 - 1; i >= 1; i--){ for(int j = 1; pri[i][j] != ‘\0‘;j++) printf("%c",pri[i][j]); if(i!=1) printf(" "); } printf("\n"); } return 0; }
AC的
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int dp[4010]; int pre[4010]; int ok[4010][4010]; char s[4010]; void print(int p) { if(pre[p] == -1){ for(int i = 0 ; i <= p ;i++){ printf("%c",s[i]); } } else{ print(pre[p]); printf(" "); for(int i = pre[p]+1; i <= p ;i++) printf("%c",s[i]); } } void solve() { int len = strlen(s); for(int i = 0;i < len ;i++){//i表示长度 for(int j = 0 ;i+j < len;j++){ if(i == 0) ok[j][j+i] = 1; //因为从小到大所以是符合这个方程的 else if(i == 1) ok[j][j+i] = (s[j] == s[j+i]); else if(s[j] == s[j+i]) ok[j][j+i] = ok[j+1][j+i-1]; } } for(int i = 0; i < len ;i++){ dp[i] = i + 1; pre[i] = i - 1;//从0到i是否回文 if(ok[0][i]) { dp[i] = 1; pre[i] = -1; continue; } for(int j = i - 1; j >= 0 ; j--){ if(ok[j+1][i]){//j表示i前面 if(dp[i] > dp[j] + 1){ dp[i] = dp[j] + 1; pre[i] = j; } } } } printf("%d\n",dp[len-1]); print(len-1);//dfs printf("\n"); } int main() { while(~scanf("%s",s)){ memset(dp,0,sizeof(dp)); memset(pre,0,sizeof(pre)); memset(ok,0,sizeof(ok)); solve(); } return 0; }
URAL1635——DP+回溯——Mnemonics and Palindromes
标签:
原文地址:http://www.cnblogs.com/zero-begin/p/4492883.html