zoukankan      html  css  js  c++  java
  • Week 10 作业 B

    题目描述:

    求序列A的最长上升子序列长度和序列AB的最长公共子序列长度

    思路:

    最长上升序列:定义状态:F[i]表示考虑前i个数得到的最大值,但是用F[i-1]更新F[i]时不知道a[i]选不选;进一步:定义F[i][j]表示考虑前i个数,并且序列以a[j]结尾时得到的最大值,则很显然F[j][j]==F[i][j](i>=j时),并且i不能小于j(因为如果小于就取不到a[j]了),所以第一维是多余的;再进一步:定义F[i]表示以a[i]为结尾的最大值,则F[i]=1+max{F[j],j<i,a[j]<a[i]}

    最长公共子序列:定义状态:F[i][j]表示考虑A的前i个数,B的前j个数的最大值;搜索过程:如果A[i]==B[i]则F[i][j]=F[i-1][j-1]+1;如果A[i]!=B[j]则F[i][j]=max(F[i-1][j],F[i][j-1]);边界条件:i<=0或j<=0时,返回0

    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    const int MAXN=5e3+5;
    int A[MAXN],B[MAXN];
    int f[MAXN];  //f[i]表示以A[i]为结尾的上升子序列长度
    int dp[MAXN][MAXN];	//dp[i][j]表示到A[i]和B[j]时的LCS长度 
    int main()
    {
    	int N,M,LIS=0,LCS=0;
    	cin>>N>>M;
    	for(int i=1;i<=N;i++)
    		scanf("%d",A+i);
    	f[1]=1,LIS=1;
    	for(int i=2;i<=N;i++)
    	{
    		for(int j=1;j<i;j++)
    		{
    			if(A[j]<A[i])
    				f[i]=max(f[i],f[j]+1);
    		}
    		f[i]=max(f[i],1);	//如果没有前面的元素都很大,则就只包括自己,或者直接初始化F[i]=1 
    		LIS=max(LIS,f[i]);
    	}
    	cout<<LIS<<' ';
    	
    	for(int i=1;i<=M;i++)
    		scanf("%d",B+i);
    	for(int i=1;i<=N;i++)
    		for(int j=1;j<=M;j++)
    		{
    			if(A[i]==B[j]) dp[i][j]=dp[i-1][j-1]+1;
    			else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
    		}
    	cout<<dp[N][M]<<endl;
    }
    

      

  • 相关阅读:
    c#参数传递几点小结
    c#线程初探(二)
    c#线程初探(一)
    c#:浅克隆和深克隆,序列化和反序列化
    c#冒泡、快速、选择和插入排序算法的项目应用
    c#运算符几点小结
    文件操作(无代码)
    不仅仅C#缺点(永远未完)
    《道德经》程序员版第五章
    《道德经》程序员版第四章
  • 原文地址:https://www.cnblogs.com/qingoba/p/12922846.html
Copyright © 2011-2022 走看看