动态规划 最长单调递增子序列

时间:2021-03-31 19:32:21   收藏:0   阅读:33

1.问题

设计一个O(N^2)时间的算法,找出由n个数组成的序列的最长单调递增子序列

2.题目分析

最长公共子序列(longest common sequence)最长公共子串(longest common substring)的区别

技术分享图片 技术分享图片

3.解题思路

数组a[]为输入的原始序列,用一个数组b[]表示a[]升序排序后的序列,找a[]中最长的单调递增数列,可以将这个问题转化为,寻找a、b两个数组最长的公共子序列。

代码实现

import java.io.*;
import java.util.Arrays;
public class Main {
	public static void main(String[] args) throws IOException {
		StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		st.nextToken();
		int n=(int)st.nval;	//输入序列长度
		int[] a=new int[n];
		for(int i=0;i<n;i++) {	//输入序列
			st.nextToken();
			a[i]=(int)st.nval;
		}
		maxlist(a,n);
	}	
    public static int maxlist(int a[],int n) {
        int b[]=new int[n];
        for(int i=0;i<n;i++) {
            b[i]=a[i];
        }
        Arrays.sort(b);	//排序
        int dp[][]=new int [n+1][n+1];	//设置为n+1*n+1,为了防止元素溢出
        int m[][]=new int [n+1][n+1];	//dp用来寻找问题的最优解,m用来记录dp是通过哪一个子问题得到的
        for(int i=0;i<n;i++) {	//初始化dp
            dp[i][0]=dp[0][i]=0;	//边界设为0
        }
        for(int i=1;i<=n;i++){	
            for(int j=1;j<=n;j++){
                if(a[i-1]==b[j-1]){	//a[i]和b[i]从下标0开始比较是否相等
                    dp[i][j]=dp[i-1][j-1]+1;
                    m[i][j]=1;
                }
                else{
                    dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
                    m[i][j]=dp[i-1][j]>dp[i][j-1]?2:3;
                }
            }
        }
        int i=n,j=n;
        int[] sub=new int [n];
        int k=0,limit=Integer.MAX_VALUE;
        while(i>=0&&j>=0){
            if(m[i][j]==1&&a[i-1]<limit){
                limit=a[i-1];
                sub[k++]=a[i-1];
                i--;j--;
            }
            else if(m[i][j]==2)
                i-=1;
            else 
                j-=1;
        }
        for(i=k-1;i>=0;i--)
            System.out.print(sub[i]+" ");
        return dp[n][n];
    }
}

4.时间复杂度:O(n^2)

原文:https://www.cnblogs.com/runaway-code/p/14601747.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!