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;
    }
    

      

  • 相关阅读:
    注解-案例
    注解(Annotation)
    适合新手看的超详细CentOS Linux 7 安装Tomcat8过程
    CentOS Linux 7 提示 lsof: 未找到命令
    解决MySql报错:1130
    Spring Boot 创建自定义的properties文件
    spring boot 使用Schedule创建轻量级定时任务
    4.Java数组模块
    3.IDEA开发工具
    2.java基础语法
  • 原文地址:https://www.cnblogs.com/qingoba/p/12922846.html
Copyright © 2011-2022 走看看