最长上升子序列(线性dp)-java

该博客主要围绕Java解决最长上升子序列问题展开。先介绍问题,给定数列求最长严格单调递增子序列长度,如给定数列最长上升子序列为4。接着阐述算法思路,引入arr和dp数组,推出状态转移方程。最后给出代码示例及运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要是解决最长上升子序列问题,推出状态转移方程。


前言

主要是解决最长上升子序列问题,推出状态转移方程。


提示:以下是本篇文章正文内容,下面案例可供参考

一、最长上升子序列问题

给定一个长度为 N的数列,求数值严格单调递增的子序列的长度最长是多少。

比如我们给定一个数列:

7
3 1 2 1 8 5 6

它的最长上升子序列就是4(即 1 2 5 6) 

二、算法思路

1.最长上升子序列思路

我们引入一个arr数组和一个dp数组,arr数组用来存储输入的数列,dp[i]表示的含义就是以第i个数为结尾的上升子序列的长度最大值。

那么当arr[i]>arr[j]时:

dp[i] = max(dp[j]+1) j = 0,1,2,3...i-1

dp数组代码:

        for(int i = 1;i <= n;i++) {
			//dp的默认值是1,数字本身算上升子序列中的一位
			dp[i] = 1;
			for(int j = 1;j <= i;j++) {
				if(arr[j] < arr[i]) {
					dp[i] = Math.max(dp[i],dp[j]+1);
				}
			}
		}

 以上述数列为例,它的dp数组如下:

1 1 2 1 3 3 4 

三、代码如下

1.代码如下(示例):


import java.io.*;
public class 最长上升子序列 {
	static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	public static void main(String[] args) throws Exception{
		int n = nextInt();
		int[] arr = new int[1010];
		for(int i = 1; i <= n;i++) {
			arr[i] = nextInt();
		}
		int[] dp = new int[1010];
		for(int i = 1;i <= n;i++) {
			//dp的默认值是1,数字本身算上升子序列中的一位
			dp[i] = 1;
			for(int j = 1;j <= i;j++) {
				if(arr[j] < arr[i]) {
					dp[i] = Math.max(dp[i],dp[j]+1);
				}
			}
		}
		int res = 0;
		for(int i = 1;i <= n;i++) {
			res = Math.max(res, dp[i]);
		}
		pw.println(res);
		pw.flush();
	}
	public static int nextInt()throws Exception {
		st.nextToken();
		return (int)st.nval;
	}
	public static long nextLong()throws Exception {
		st.nextToken();
		return (long)st.nval;
	}
	public static String nextLine()throws Exception {
		return br.readLine();
	}
}

2.读入数据

代码如下(示例):

7
3 1 2 1 8 5 6

3.代码运行结果

4

最长上升子序列是 :1、2、5、6。长度是4


总结

最长上升子序列我们主要从dp数组中找出状态转移方程即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值