HDU-1423 Greatest Common Increasing Subsequence ACM解题报告(O(n^2)递推算法)

这题就是求两个序列的LCIS。关于LCIS的内容前面的博文中讲的很详细了。

这题是我自己敲的代码,我原先看了那个博文以为自己懂了,其实发现我错了,真的是只有自己敲得时候才能发现自己的漏洞,所以我思考了好久,终于完全透彻的理解了LCIS的算法,并且用O(n^2)的算法实现之。所以得要多敲题,多思考,而不仅仅是表面的看看。

状态转移方程:

a[i]!=b[j]:   F[i][j]=F[i-1][j]

a[i]==b[j]:   F[i][j]=max(F[i-1][k])+1 1<=k<=j-1&&b[j]>b[k]

#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<stack>
using namespace std;
#define MAX 105
typedef long long LL;
const double pi=3.141592653589793;
const int INF=1e9;
const double inf=1e20;
LL a[505],b[505];
int d[505][505];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m,maxn;
        scanf("%d",&n);
        memset(d,0,sizeof(d));
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        scanf("%d",&m);
        for(int i=1;i<=m;i++) scanf("%lld",&b[i]);
        for(int i=1;i<=n;i++)
        {
            maxn=0;
            for(int j=1;j<=m;j++)
            {
                d[i][j]=d[i-1][j];//这个算法是以b[j]为结尾的一断序列。如果b[j]和a[i]不相等,就是这个式子的结果
                if(a[i]>b[j]&&maxn<d[i-1][j]) maxn=d[i-1][j];//维护更新maxn的值,直到找到a[i]=b[j]之前。
                else if(a[i]==b[j]) d[i][j]=maxn+1;//以b[j]为结尾的LCIS的长度
            }
        }
        maxn=0;
        for(int i=1;i<=m;i++) if(maxn<d[n][i]) maxn=d[n][i];//由于这个数组是按照b[i]结尾的LCIS的长度,所以要遍历b数组
        printf("%d\n",maxn);
        if(t) printf("\n");
    }
    return 0;
}


你可能感兴趣的:(动态规划,ACM)