UVa:11404 Palindromic Subsequence(动态规划)

来源:互联网 发布:万网域名管理地址 编辑:程序博客网 时间:2024/05/17 22:07

问题可以转化成LCS输出最小字典序。

用了一种很笨的办法,直接保存dp过程中的每个公共字符串,这样在两个字符不等时且dp【i-1】【j】==dp【i】【j-1】时来比较两个公共字符串的字典序来确定i,j位置的字符串。这样输出也不用倒推回去了,但是空间复杂度比较高。另外有一个问题时此题要求输出回文,这样得到的结果可以不是回文,所以取前半部分然后逆置出后半部分即是答案。

用了1.2S

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <map>#include <algorithm>#define ll long long#define INF 2139062143#define inf -2139062144#define MOD 20071027#define MAXN 1005using namespace std;int dp[MAXN][MAXN];string path[MAXN][MAXN];string str1,str2;int main(){    ios::sync_with_stdio(false);    while(cin>>str1)    {        str2.clear();        int l=str1.size();        for(int i=l-1; i>=0; --i)            str2+=str1[i];        str1='0'+str1;        str2='0'+str2;        memset(dp,0,sizeof(dp));        for(int i=1; i<=l; ++i)            for(int j=1; j<=l; ++j)                if(str1[i]==str2[j])                {                    dp[i][j]=dp[i-1][j-1]+1;                    path[i][j]=path[i-1][j-1]+str1[i];                }                else                {                    if(dp[i-1][j]==dp[i][j-1])                    {                        dp[i][j]=dp[i-1][j];                        path[i][j]=min(path[i-1][j],path[i][j-1]);                    }                    else                    {                        if(dp[i-1][j]>dp[i][j-1])                        {                            dp[i][j]=dp[i-1][j];                            path[i][j]=path[i-1][j];                        }                        else                        {                            dp[i][j]=dp[i][j-1];                            path[i][j]=path[i][j-1];                        }                    }                }        string ans;        for(int i=0; i<=(dp[l][l]-1)/2; ++i)            ans+=path[l][l][i];        int st;        if(dp[l][l]%2==0) st=ans.size()-1;        else st=ans.size()-2;        for(int i=st; i>=0; --i)            ans+=ans[i];        cout<<ans<<endl;    }    return 0;}


 用滚动数组优化之后时间变成了0.8S

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <map>#include <algorithm>#define ll long long#define INF 2139062143#define inf -2139062144#define MOD 20071027#define MAXN 1005using namespace std;int dp[3][MAXN];string path[3][MAXN];string str1,str2;int main(){    ios::sync_with_stdio(false);    while(cin>>str1)    {        str2.clear();        int l=str1.size();        for(int i=l-1; i>=0; --i)            str2+=str1[i];        str1='0'+str1;        str2='0'+str2;        memset(dp,0,sizeof(dp));        for(int i=0; i<=l; ++i)        {            path[0][i].clear();            path[1][i].clear();        }        for(int i=1; i<=l; ++i)            for(int j=1; j<=l; ++j)                if(str1[i]==str2[j])                {                    dp[i&1][j]=dp[(i+1)&1][j-1]+1;                    path[i&1][j]=path[(i+1)&1][j-1]+str1[i];                }                else                {                    if(dp[(i+1)&1][j]==dp[i&1][j-1])                    {                        dp[i&1][j]=dp[(i+1)&1][j];                        path[i&1][j]=min(path[(i+1)&1][j],path[i&1][j-1]);                    }                    else                    {                        if(dp[(i+1)&1][j]>dp[i&1][j-1])                        {                            dp[i&1][j]=dp[(i+1)&1][j];                            path[i&1][j]=path[(i+1)&1][j];                        }                        else                        {                            dp[i&1][j]=dp[i&1][j-1];                            path[i&1][j]=path[i&1][j-1];                        }                    }                }        string ans;        for(int i=0; i<=(dp[l&1][l]-1)/2; ++i)            ans+=path[l&1][l][i];        int st;        if(dp[l&1][l]%2==0) st=ans.size()-1;        else st=ans.size()-2;        for(int i=st; i>=0; --i)            ans+=ans[i];        cout<<ans<<endl;    }    return 0;}


 

0 0
原创粉丝点击