hdu 1423 最长公共递增子序列

这题一开始把我给坑了,我还没知道LCIS的算法,然后就慢慢搞吧,幸运的是还真写出来了,只不过麻烦了一点。

我是将该题转换为多条线段相交,然后找出最多多少条不相交,并且其数值死递增的。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[510][510];
int list1[510],list2[510];
struct Edge{
    int val,vex[510];
    int pos;
}p[510];
void init()
{
    int i,j;
    for(i=0;i<=500;i++)
        for(j=0;j<=500;j++)
            dp[i][j]=1;
    for(i=0;i<=500;i++)
        p[i].pos=0;
}

int main()
{
    int t,n,m,i,j,k,r,f;
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&list1[i]);
        scanf("%d",&m);
        for(i=1;i<=m;i++)
            scanf("%d",&list2[i]);
        int f=0;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(list1[i]==list2[j])
                {
                    p[i].val=list1[i];
                    p[i].vex[p[i].pos++]=j;
                    f=1;
                }
            }
        }
        /*for(i=1;i<=n;i++)
        {
            cout<<" ** "<<p[i].val<<" ** :";
            for(j=0;j<p[i].pos;j++)
                cout<<p[i].vex[j]<<" ";
            cout<<endl;
        }*/
        int Max=0;
        if(f)
            Max=1;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<i;j++)
            {
                if(p[i].val>p[j].val)
                {
                    //cout<<"ok"<<endl;
                    //cout<<p[i].val<<"   "<<p[j].val<<endl;
                    for(k=0;k<p[i].pos;k++)
                    {
                        for(r=0;r<p[j].pos;r++)
                        {
                            if(p[i].vex[k]>p[j].vex[r])
                                dp[i][p[i].vex[k]]=max(dp[i][p[i].vex[k]],dp[j][p[j].vex[r]]+1);
                            if(dp[i][p[i].vex[k]]>Max)
                            {
                                Max=dp[i][p[i].vex[k]];
                                //cout<<Max<<endl;
                            }
                        }
                    }
                }
            } 
        }
        printf("%d\n",Max);
        if(t)
            printf("\n");
    }
    return 0;
}


正解的代码有如下两种版本,一种是一维数组,一种二维。思想是一样的。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[510][510],a[510],b[510];
int LCIS(int n,int m)
{
    int i,j,k,temp;
    int ans=0;
    memset(dp,0,sizeof(dp));
    for(i=1;i<=n;i++)
    {
        temp=0;
        for(j=1;j<=m;j++)
        {
            dp[i][j]=dp[i-1][j];
            if(a[i]==b[j]) dp[i][j]=temp+1;
            if(a[i]>b[j]&&dp[i-1][j]>temp)
                temp=dp[i-1][j];
            if(ans<dp[i][j])
                ans=dp[i][j];
        }
    }
    return ans;
}
int main()
{
    int t,n,m,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        scanf("%d",&m);
        for(i=1;i<=m;i++)
            scanf("%d",&b[i]);
        printf("%d\n",LCIS(n,m));
        if(t)
            printf("\n");
    }
}
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[510],a[510],b[510];
int LCIS(int n,int m)
{
    int i,j,k;
    memset(f,0,sizeof(f));
    for(i=1;i<=n;i++)
    {    
        k=0;
        for(j=1;j<=m;j++)
        {    
            if(a[i]==b[j])
                f[j]=max(f[j],k+1);
            if(a[i]>b[j]&&f[j]>k)
                k=f[j];
            //cout<<k<<endl;
        }
    }
    int ans=0;
    for(i=0;i<=m;i++)
        ans=max(ans,f[i]);
    return ans;
}
int main()
{
    int t,n,m,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        scanf("%d",&m);
        for(i=1;i<=m;i++)
            scanf("%d",&b[i]);
        printf("%d\n",LCIS(n,m));
        if(t)
            printf("\n");
    }
}

 

posted @ 2013-07-06 19:06  fangguo  阅读(172)  评论(0编辑  收藏  举报