ZOJ - 2432 最长公共上升子序列

应该是一道浅层的动态规划题吧,emmmm理解了一下午加一晚上,还问了强哥,也是似懂非懂吧,就是记录路径,说实话滚动数组不太好理解(至少我是这么认为的。。。。。。)这道题目需要记录路径。这里给出我看的博客点击打开链接

#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <cstring>
#include <map>
#include <vector>
#include <ctype.h>
using namespace std;
const int maxn = 505;
int num,ans,a[maxn],b[maxn],px[maxn][maxn],py[maxn][maxn],dp[maxn][maxn];
void Printf(int x,int y)
{
    if(!dp[x][y])
        return;
    if(px[x][y]!=-1&&py[x][y]!=-1)
    {
        int tx = px[x][y],ty = py[x][y];
        Printf(tx,ty);
        if(dp[x][y]!=dp[tx][ty])
        {
            num++;
            if(num<ans)
                printf("%d ",b[y]);
            else
                printf("%d",b[y]);
        }
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m;
        cin>>n;
        for(int i=1; i<=n; i++)
            cin>>a[i];
        cin>>m;
        for(int i=1; i<=m; i++)
            cin>>b[i];
        memset(dp,0,sizeof(dp));
        memset(px,-1,sizeof(px));
        memset(py,-1,sizeof(py));
        for(int i = 1; i<=n; i++)
        {
            int mmax = 0,tx = 0,ty = 0;
            for(int j=1; j<=m; j++)
            {
                dp[i][j] = dp[i-1][j];
                px[i][j] = i - 1;
                py[i][j] = j;
                if(a[i]>b[j]&&mmax<dp[i-1][j])
                    mmax = dp[i-1][j],tx = i - 1,ty = j;
                if(a[i]==b[j])
                    dp[i][j] = mmax + 1,px[i][j] = tx,py[i][j] = ty;
            }
        }
        int sign = -1;
        ans = 0;
        for(int j=1; j<=m; j++)
        {
            if(dp[n][j]>ans)
            {
                ans = dp[n][j];
                sign = j;
            }
        }
        num = 0;
        printf("%d\n",ans);
        Printf(n,sign);
        cout<<endl;
        if(t)
            cout<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sgsyacm/article/details/80055149