求最长递增子序列是动态规划的经典问题之一,其思想与求最大子序列之和类似,区别就在于前者还需要判断前面的元素与当前元素的大小关系。
首先是使用递归的方法:
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1000 + 10;
int arr[N], dp[N];
int Func(int n){
if(dp[n] != -1) return dp[n];
if(n == 0) return 1;
int ans = 1;
for(int i = 0; i < n; i++){
if(arr[i] < arr[n]){
ans = max(ans, Func(i) + 1);
}
}
dp[n] = ans;
return ans;
}
int main(){
int n;
while(scanf("%d", &n) != EOF){
for(int i = 0; i < n; i++) scanf("%d", &arr[i]);
fill(dp, dp + n, -1);
int maximum = 0;
for(int i = 0; i < n; i++) maximum = max(maximum, Func(i));
printf("%d\n", maximum);
}
return 0;
}
也可以递推得到:
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1000 + 10;
int arr[N], dp[N];
void Func(int n){
for(int i = 0; i < n; i++){
int ans;
if(i == 0) ans = 1;
else{
ans = 1;
for(int j = 0; j < i; j++){
if(arr[j] < arr[i]){
ans = max(ans, dp[j] + 1);
}
}
}
dp[i] = ans;
}
}
int main(){
int n;
while(scanf("%d", &n) != EOF){
for(int i = 0; i < n; i++) scanf("%d", &arr[i]);
fill(dp, dp + n, -1);
int maximum = 0;
Func(n);
for(int i = 0; i < n; i++) maximum = max(maximum, dp[i]);
printf("%d\n", maximum);
}
return 0;
}