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");

    }

}

 

你可能感兴趣的:(HDU)