HDU1423&POJ2127-Greatest Common Increasing Subsequence

来源:互联网 发布:原油数据影响大吗 编辑:程序博客网 时间:2024/06/09 23:40

Greatest Common Increasing Subsequence

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7674 Accepted Submission(s): 2484

Problem Description
This is a problem from ZOJ 2432.To make it easyer,you just need output the length of the subsequence.

Input
Each sequence is described with M - its length (1 <= M <= 500) and M integer numbers Ai (-2^31 <= Ai < 2^31) - the sequence itself.

Output
output print L - the length of the greatest common increasing subsequence of both sequences.

Sample Input
1

5
1 4 2 5 -12
4
-12 1 2 4

Sample Output
2

Source
ACM暑期集训队练习赛(二)

题目大意: 最长公共上升子序列
解题思路: 动态规划
dp[i][j]表示,s1串的前i个与s2串的前j个,且以s2[j]结尾的LCIS,
状态转移方程:

if(s1[i]==s2[j])    dp[i][j]=max(dp[i'][j'])+1; (i'<i&&j'<j&&s2[j']<s1[i]==s2[j])else    dp[i][j]=dp[i-1][j];
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include<cctype>#include<queue>using namespace std;const int MAXN=505;int s1[MAXN],s2[MAXN];int dp[MAXN][MAXN];int main(){    int T;    int M1,M2;    cin>>T;    while(T--)    {        cin>>M1;        for(int i=1;i<=M1;i++)            cin>>s1[i];        cin>>M2;        for(int i=1;i<=M2;i++)            cin>>s2[i];        memset(dp,0,sizeof(dp[0])*(M1+5));        int Max;        for(int i=1;i<=M1;i++)        {            Max=0;            for(int j=1;j<=M2;j++)            {                dp[i][j]=dp[i-1][j];                if(s1[i]>s2[j]&&dp[i-1][j]>Max) Max=dp[i-1][j];                if(s1[i]==s2[j]) dp[i][j]=Max+1;            }        }        int ans=0;        for(int j=0;j<=M2;j++)            ans=max(ans,dp[M1][j]);        cout<<ans<<endl;        if(T!=0) cout<<endl;    }    return 0;}

POJ中加了一个打印路径的要求,用一个数组记录从哪儿转移过来的,反推路径即可

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include<cctype>#include<queue>using namespace std;const int MAXN=505;int s1[MAXN],s2[MAXN];int dp[MAXN][MAXN];int path[MAXN][MAXN];int res[MAXN];//if(s1[i]==s2[j])//    dp[i][j]=max(dp[i'][j'])+1; (i'<i&&j'<j&&s2[j']<s1[i]==s2[j])//else//    dp[i][j]=dp[i-1][j];int main(){    ios::sync_with_stdio(false);    int M1,M2;    while(cin>>M1)    {        for(int i=1;i<=M1;i++)            cin>>s1[i];        cin>>M2;        for(int i=1;i<=M2;i++)            cin>>s2[i];        memset(dp,0,sizeof(dp));        memset(path,0,sizeof(path));        int Max,Maxj;        int ai=0,aj=0;        int ans=0;        for(int i=1;i<=M1;i++)        {            Max=0;            Maxj=0;            for(int j=1;j<=M2;j++)            {                dp[i][j]=dp[i-1][j];                path[i][j]=-1;                if(s2[j]<s1[i]&&dp[i-1][j]>Max)                {                     Max=dp[i-1][j];                     Maxj=j;                }                else if(s1[i]==s2[j])                {                    dp[i][j]=Max+1;                    path[i][j]=Maxj;                }                if(ans<dp[i][j])                {                    ans=dp[i][j];                    ai=i;                    aj=j;                }            }        }        cout<<ans<<endl;        int cnt=ans;        while(cnt)        {            if(path[ai][aj]>-1)            {                res[cnt--]=s2[aj];                aj=path[ai][aj];            }            ai--;        }        cout<<res[1];        for(int i=2;i<=ans;i++)        {            cout<<" "<<res[i];        }        cout<<endl;    }    return 0;}
阅读全文
0 0
原创粉丝点击