回文子串dp,最小字典序的话需要记录一下,注意是string型的,不能只记录一个字符,因为可能出现相等的情况
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<string> #define len first #define str second #define MAXN 1005 #define pii pair<int,int> #define pis pair<int,string> using namespace std; pis dp[MAXN][MAXN]; pii g[MAXN][MAXN]; int n; char s[MAXN]; int b[MAXN][MAXN]; int p[MAXN]; string e; pis f(int L,int R){ if(b[L][R]){ return dp[L][R]; } b[L][R]=1; pis& ans=dp[L][R]; if(L>R){ return ans=make_pair(0,e); } if(L==R){ g[L][R]=make_pair(-1,-1); string t(1,s[L]); return ans=make_pair(1,t); } ans.len=-1,ans.str=-1; if(s[L]==s[R]){ ans=f(L+1,R-1); string t(1,s[L]);t+=ans.str; ans.len+=2,ans.str=t; if(L+1<R)g[L][R]=make_pair(L+1,R-1); else g[L][R]=make_pair(-1,-1); } if(ans<f(L,R-1)){ ans=f(L,R-1); g[L][R]=make_pair(L,R-1); } if(ans<f(L+1,R)){ ans=f(L+1,R); g[L][R]=make_pair(L+1,R); } return ans; } void print(int L,int R){ if(g[L][R]==make_pair(-1,-1)){ p[L]=p[R]=1; return; } if(g[L][R].first==L+1&&g[L][R].second==R-1){ p[L]=p[R]=1; } print(g[L][R].first,g[L][R].second); } int main() { // freopen("data.in","r",stdin); // freopen("my.out","w",stdout); while(~scanf("%s",s+1)){ memset(b,0,sizeof(b)); memset(p,0,sizeof(p)); n=strlen(s+1); for(int i=1;i<=n;i++){ s[i]=200-s[i]; } f(1,n); print(1,n); for(int i=1;i<=n;i++){ if(p[i])printf("%c",200-s[i]); } printf(" "); } return 0; }