主要是解决最长上升子序列问题,推出状态转移方程。
文章目录
前言
一、最长上升子序列问题
二、算法思路
1.最长上升子序列思路
三、代码如下
1.代码如下(示例):
2.读入数据
3.代码运行结果
总结
前言
主要是解决最长上升子序列问题,推出状态转移方程。
提示:以下是本篇文章正文内容,下面案例可供参考
一、最长上升子序列问题
给定一个长度为 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数组代码:
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数组中找出状态转移方程即可。