• Codeforces 10D LCIS


    https://vjudge.net/problem/CodeForces-10D

    题目

    给两个序列,求他们的最长上升公共子序列。每个序列的长度小于等于500。

    题解

    设$dp[i][j]$为以$j$为结尾的最长上升公共子序列的长度,那么

    当$a[i]==b[j]$时$displaystyle dp[i][j]=(max_{p<i,q<j,b[q]<b[j]} dp[p][q])+1$

    当$a[i]!=b[j]$时$displaystyle dp[i][j]=max_{p<i} dp[p][j]$

    这样时间复杂度是$O(n^4)$

    可以通过数学归纳法,优化重复计算的max

    先优化不等的部分,根据贪心可以知道p小答案不会更优,那么$dp[i][j]=dp[i-1][j]$

    然后优化等于的部分,根据贪心可以知道p小答案不会更优,那么$displaystyle dp[i][j]=(max_{q<j,b[q]<b[j]} dp[i-1][q])+1$

    然后在循环的时候,已经循环过一次j,可以在循环的时候记录$displaystylemax_{q<j,b[q]<b[j]} dp[i-1][q]$

    为了输出结果,还需要记录每个位置的转移,然后倒过来输出就可以了(答案为0时不输出)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define REP(i,a,b) for(register int i=(a); i<(b); i++)
    #define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
    #define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
    using namespace std;
    typedef long long ll;
    int dp[507][507], ch[507][507];
    int a[507], b[507];
    int n,m;
    inline void go(int x) {
    	if(~ch[n-1][x]) go(ch[n-1][x]);
    	printf("%d ", b[x]);
    }
    int main() {
    	scanf("%d", &n);
    	REP(i,0,n) { scanf("%d", &a[i]); }
    	scanf("%d", &m);
    	REP(i,0,m) { scanf("%d", &b[i]); }
    	memset(dp,0,sizeof dp);
    	memset(ch,-1,sizeof ch);
    	REP(i,0,n) {
    		int k=-1, v=0;
    		REP(j,0,m) {
    			if(a[i]==b[j]) {
    				//dp[i][j] = max(dp[i-1][1..j-1])+1 [b[k]<a[i]]
    				dp[i][j] = v+1;
    				ch[i][j] = k;
    			} else {
    				if(i) dp[i][j] = dp[i-1][j], ch[i][j]=ch[i-1][j];
    			}
    			if(i && b[j]<a[i]) {
    				if(v<dp[i-1][j]) {
    					v=dp[i-1][j];
    					k=j;
    				}
    			}
    		}
    	}
    	int ans=0, x=-1;
    	REP(j,0,m) if(ans<dp[n-1][j]) {
    		ans = dp[n-1][j];
    		x = j;
    	}
    	printf("%d
    ", ans);
    	if(ans) {
    		if(~ch[n-1][x]) go(ch[n-1][x]);
    		printf("%d", b[x]);
    	}
    	putchar('
    ');
    }
    
  • 相关阅读:
    Python开发环境Spyder介绍
    Python干货整理之数据结构篇
    通过Python爬虫按关键词抓取相关的新闻
    疫情后来场说走就走的旅行,Python制作一份可视化的旅行攻略
    详细介绍去一年在 PyPI 上下载次数最多的 Python 包
    Python错误与异常
    python爬虫爬取2020年中国大学排名
    微信史上最短的一行功能代码:拍一拍
    Python爬取某宝商品数据案例:100页的价格、购买人数等数据
    我的SAS菜鸟之路7
  • 原文地址:https://www.cnblogs.com/sahdsg/p/12380363.html
Copyright © 2020-2023  润新知