zoukankan      html  css  js  c++  java
  • 【CF10D】 LCIS

    题目链接

    最长公共上升子序列

    \(f[i][j]\)表示\(A\)的前\(i\)个数,匹配\(B\)的第\(j\)个数,且\(B[j]\)必选时的最长公共上升子序列长度

    转移:

    if(A[i]==B[j]) dp[i][j]=max(dp[i-1][k])+1; k=[1,2,...,j-1],B[k]<B[j]=A[i]
    else dp[i][j]=dp[i-1][j];
    

    记录一下\(dp[i-1][j]\)最大的\(B[k]<B[j]\),优化到\(O(n^2)\)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    const int MAXN=510;
    
    inline int read(){
    	int x=0; char c=getchar();
    	while(c<'0') c=getchar();
    	while(c>='0') x=x*10+c-'0',c=getchar();
    	return x;
    }
    
    int n,m,A[MAXN],B[MAXN];
    int dp[MAXN][MAXN],g[MAXN][MAXN],pre[MAXN][MAXN];
    
    inline void dfs(int i,int x){
    	if(!x) return;
    	dfs(i-1,pre[i][x]);
    	if(pre[i][x]!=x)
    		printf("%d ",B[x]);
    }
    
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)
    		A[i]=read();
    	m=read();
    	for(int i=1;i<=m;++i)
    		B[i]=read();
    	for(int i=1;i<=n;++i){
    		int k=0;
    		for(int j=1;j<=m;++j){
    			dp[i][j]=dp[i-1][j];
    			pre[i][j]=j;
    			if(A[i]==B[j])
    				dp[i][j]=dp[i-1][k]+1,pre[i][j]=k;
    			if(B[j]<A[i]&&dp[i-1][j]>dp[i-1][k]) k=j;
    		}
    	}
    	int Ans=0,k=0;
    	for(int i=1;i<=m;++i)
    		if(dp[n][i]>Ans) Ans=dp[n][i],k=i;
    	printf("%d\n",Ans);
    	dfs(n,k);
    	return 0;
    }
    
  • 相关阅读:
    搜狗搜索用户体验
    第六周学习进度条
    对我们团队NBPL的改进方案意见
    钱多多软件制作第七天
    团队冲刺第二周05
    团队冲刺第二周04
    团队冲刺第二周03
    输入法评价
    团队冲刺第二周02
    团队冲刺第二周01
  • 原文地址:https://www.cnblogs.com/66-CCF-F/p/11813723.html
Copyright © 2011-2022 走看看