zoukankan      html  css  js  c++  java
  • 【poj2127】 Greatest Common Increasing Subsequence

    http://poj.org/problem?id=2127 (题目链接)

    题意

      计算两个序列$a$和&b$的最长公共上升子序列。

    Solution

      爸爸的$n^3$算法莫名其妙RE了,不爽之下学习了一发$n^2$的。

      http://www.cnblogs.com/dream-wind/archive/2012/08/25/2655641.html

      $f[i][j]$表示序列$a$的前$i$位,序列$b$的前$j$位,以$b_j$结尾的最长公共上升子序列长度。

      转移:$$f[i][j]=f[i-1][j](a_i!=b_j)$$

    $$f[i][j]=max_{1<=k<j}f[i-1][k]+1(a_i=b_j)$$

      这样直接做的话是$n^3$的,我们用前缀最大值优化一下,然后记录方案即可。

    代码

    // poj2127
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf (1ll<<60)
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=1000;
    int a[maxn],b[maxn],f[maxn][maxn],p[maxn][maxn],ans[maxn];
    int n,m;
    
    int main() {
    	while (scanf("%d",&n)!=EOF) {
    		for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    		scanf("%d",&m);
    		for (int i=1;i<=m;i++) scanf("%d",&b[i]);
    		int sum=0,ai,aj;
    		for (int i=1;i<=n;i++) {
    			int mx=0,mj=0;
    			for (int j=1;j<=m;j++) {
    				f[i][j]=f[i-1][j];
    				p[i][j]=-1;
    				if (b[j]<a[i] && f[i-1][j]>mx) mx=f[i-1][j],mj=j;
    				else if (a[i]==b[j]) f[i][j]=mx+1,p[i][j]=mj;
    				if (sum<f[i][j]) sum=f[i][j],ai=i,aj=j;
    			}
    		}
    		printf("%d
    ",sum);
    		int tmp=sum;
    		for (;ai;ai--) if (p[ai][aj]>-1) ans[tmp--]=b[aj],aj=p[ai][aj];
    		for (int i=1;i<=sum;i++) printf("%d ",ans[i]);
    		puts("");
    	}
        return 0;
    }
    
  • 相关阅读:
    Docker多主机互联
    数据结构
    广度优先算法走出迷宫
    golang反射
    waitGroup的使用
    golang中的mutex锁
    goroutine和channel
    如何优雅的关闭Golang Channel?
    使用context关闭协程以及协程中的协程
    golang对不同系统的编译
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6418393.html
Copyright © 2011-2022 走看看