Subject address: Ural 1635
It is also the DP of the output path... I have done a lot of work ..
Status transfer is quite simple. All the input strings must be preprocessed first. If tag [I] [J] is 1, the input string I -- J is a input string. Otherwise, the input string is not a input string. During preprocessing, we need to use the N ^ 2 method, that is, to enumerate the center of the input string, which can be divided into two types: odd and even.
Then the DP transition equation is, if tag [J] [I] = 1, DP [I] = min (DP [I], DP [J-1] + 1 );
For the most annoying path output, you can use pre to record the forward Split points of the input string, and then output the data based on these Split points.
The Code is as follows:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <stdlib.h>#include <math.h>#include <ctype.h>#include <queue>#include <map>#include <set>#include <algorithm>using namespace std;#define LL __int64const int INF=0x3f3f3f3f;char s[5000];int dp[5000], tag[4001][4001], len, pre[4001], a[4001];void init(){ int i, j, k, l, r; memset(tag,0,sizeof(tag)); for(i=0;i<len;i++) tag[i][i]=1; for(i=1;i<len;i++) { for(j=1;j<=i;j++) { l=i-j;r=i+j; if(r>=len) break; if(s[l]==s[r]) { tag[l][r]=1; } else break; } } for(i=0;i<len-1;i++) { if(s[i]==s[i+1]) { tag[i][i+1]=1; for(j=1;j<=i;j++) { l=i-j;r=i+j+1; if(r>=len) break; if(s[l]==s[r]) { tag[l][r]=1; } else break; } } }}int main(){ int i, j, k, cnt; scanf("%s",s); len=strlen(s); init(); dp[0]=0; memset(pre,-1,sizeof(pre)); for(i=1;i<=len;i++) { dp[i]=dp[i-1]+1; pre[i]=i-1; for(j=1;j<i;j++) { if(tag[j-1][i-1]) { if(dp[i]>dp[j-1]+1) { dp[i]=dp[j-1]+1; pre[i]=j-1; } } } } printf("%d\n",dp[len]); cnt=0; for(i=len;i!=-1;i=pre[i]) { a[++cnt]=i; //printf("%d ",a[cnt-1]); } sort(a+1,a+cnt+1); /*for(i=1;i<=cnt;i++) { printf("%d ",a[i]); }*/ for(i=2;i<=cnt;i++) { for(j=a[i-1];j<a[i];j++) { printf("%c",s[j]); } if(i!=cnt) printf(" "); else puts(""); } return 0;}
Ural 1635 mnemonics and palindromes (DP)