머리말
동적 프로그래밍과 같은 문제는 항상 모든 사람이 알고리즘 학습에서 접하는 가장 어려운 문제 중 하나였습니다. 한 종류의 문제는 선형 DP라고도 하는 선형입니다. 오늘은 가장 긴 오름차순 부분수열 I을 분석해 보겠습니다.
주제 정보
给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。
참고: 여기에서 하위 시퀀스 요구 사항은 엄격하게 단조 증가합니다. 예를 들어 1, 2, 3, 4. 1, 1, 2, 3, 4가 될 수 없습니다.
입력 형식
第一行包含整数 N。
第二行包含 N 个整数,表示完整序列。
출력 형식
输出一个整数,表示最大长度。
데이터 범위
이 질문의 데이터 범위:
1≤N≤100000, −109≤数列中的数≤109
알고리즘 질문의 주요 목적은 알고리즘이 수행될 수 있다는 전제 하에 알고리즘의 시간 복잡도를 최적화하는 것이므로 질문의 데이터 범위는 주의가 필요한 지점입니다.
견본
입력하다:
7 3 1 2 1 8 5 6
산출:
4
아이디어
원래 분석 아이디어의 저자: Yan Xuecan. 웹사이트AcWing
제가 잘 이해하지 못하는 사진이 하나 있을 수 있습니다. 예를 들어보겠습니다.
3 1 2 1 8 5 6
설명:
集合:
상태가 나타내는 집합은 특정 숫자로 끝나는 집합을 의미합니다. 예를 들어, 숫자 8의 집합은 {1,8}, {3,8}, {2,8}, {1,8}을 포함합니다.
属性:
그러나 f[i]는 구체적인 값입니다. 이 값은 이러한 집합 중 가장 긴 집합 길이를 나타냅니다. 여기 2가 있습니다.
状态计算:
각 집합은 i번째 숫자로 끝나므로 각 숫자에는 숫자 i가 포함됩니다. 아래의 타원은 i-1번째 숫자에서 이러한 집합을 클래스로 나누는 것을 나타냅니다.
첫 번째 유형: i-1번째 숫자가 0, 즉 부분 수열의 길이가 1이고 i-1번째 숫자가 없습니다
. 두 번째 유형: i-1번째 숫자가 1이고, 가장 긴 오름차순 부분 수열의 길이는 i-1+ i, 즉 f[1]+1입니다
. 세 번째 유형: i-2번째 숫자는 2이고 가장 긴 오름차순 부분 수열의 길이는 i-2+ i입니다. , 즉, f[2 ]+1
...
i-1th: i-1번째 숫자는 i-1이고 가장 긴 오름차순 부분 수열의 길이는 i-1+ 1입니다. 즉, f[i-1 ]+1
이러한 시퀀스는 가장 긴 오름차순 부분 시퀀스이기 때문에 반드시 존재하는 것은 아니므로 [i]>a[j]도 충족되어야 합니다. i는 마지막 숫자이므로 j는 그보다 작아야 합니다.
글쎄, 그것에 대해 생각한 후에 코드 작성을 시작할 수 있습니다.
암호
import java.util.Scanner;
public class Main {
static int N=1010;
//题目给的子序列
static int a[]=new int[N];
//状态表示的数组
static int f[]=new int[N];
public static void main (String[] args) {
Scanner sc=new Scanner (System.in);
int n=sc.nextInt ();
for (int i = 1 ; i <=n ; i++) {
a[i]=sc.nextInt ();
}
//f[i]表示最长上升子序列的最大长度
for (int i = 1 ; i <=n ; i++) {
f[i]=1;
//f[i]=1 这时只有i一个数,所以f[1]=1;
for (int j = 1 ; j <i ; j++) {
if(a[j]<a[i]){
f[i]=Math.max (f[i],f[j]+1);
}
}
}
//求出所有f的集合后,在遍历一遍f,求出最长的子序列的长度。
int res=0;
for (int i = 1 ; i <=n ; i++) {
res=Math.max (res,f[i]);
}
System.out.println (res);
}
}