(2.16) The problem of the longest ascending subsequence

Problem (DP)

Insert picture description here

Code

Scheme 1: O(n 2 )
dp[i] := the length of the longest ascending subsequence ending in a[i]

Since there are only two cases for a subsequence ending in a[i]:
(1) A sequence containing only a[i]
(2) A[j] that satisfies j <i and a[j] <a[i] The subsequence obtained by adding a[i] to the end of the ascending subsequence at the end

Therefore, the recurrence relationship is as follows:
dp[i] = max{1, dp[j] + 1 | j <i and a[j] <a[i]}

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int MAX_N = 1000; 
int dp[MAX_N+1]; // DP数组 

//输入 
int n = 5;   
int a[5] = {
    
    4, 2, 3, 1, 5};

void solve(){
    
    
	int res = 0;
	for(int i = 0 ; i < n ; i ++){
    
    
		dp[i] = 1;
		for(int j = 0 ; j < i ; j ++){
    
    
			if(a[j] < a[i]){
    
    
				dp[i] = max(dp[i], dp[j]+1);
			}
		}
		res = max(res, dp[i]);
	}
	printf("%d\n", res);
} 

int main(){
    
    	
	solve(); 
	return 0;
}

Scheme 2: O(nlogn)
Insert picture description here

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int MAX_N = 1000; 
const int INF = 100000;
int dp[MAX_N+1]; // DP数组 

//输入 
int n = 5;   
int a[5] = {
    
    4, 2, 3, 1, 5};

void solve(){
    
    
	fill(dp, dp+n, INF);
	for(int i = 0 ; i < n ; i ++)
		*lower_bound(dp, dp+n, a[i]) = a[i];
	printf("%d\n",lower_bound(dp, dp+n, INF) - dp);
} 	


int main(){
    
    	
	solve(); 
	return 0;
}

Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_36321330/article/details/106919063