acwing 895. 最長上升子序列
阿新 • • 發佈:2022-02-24
給定一個長度為 N 的數列,求數值嚴格單調遞增的子序列的長度最長是多少。
輸入格式
第一行包含整數 N。
第二行包含 N 個整數,表示完整序列。
輸出格式
輸出一個整數,表示最大長度。
資料範圍
1≤N≤1000,
−109≤數列中的數≤109
輸入樣例:
7
3 1 2 1 8 5 6
輸出樣例:
4
錯誤的做法,
這個做法錯誤的原因是:列舉以a[i]為開始的上升序列無法找到最長的,比如 1 2 8 5 6, 下面的做法以1開始只能找到1 2 8,所以列舉以a[i]開始的最長子序列行不通,所以想到 看以a[i]為結尾的最長子序列,從而想到下一個動態規劃的做法
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; const int N = 1010; int a[N], f[N]; int n; int main() { // 暴力做法 scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); int res = 0; for(int i = 1; i <= n; i++) { int p = 1; int t = a[i]; for(int j = i+1; j <= n; j++) { if(a[j] > t) { t = a[j]; p++; } } res = max(res, p); } cout << res << endl; return 0; }
正確做法
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; const int N = 1010; int a[N], f[N]; int n; int main() { // f[i]表示以a[i]結尾的最長上升子序列的長度 // f[i] = max(f[j]) + 1 (if a[j] < a[i]) scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); // 初始化 for(int i = 1; i <= n; i++) f[i] = 1; for(int i = 1; i <= n; i++) { for(int j = 1; j < i; j++) { if(a[j] < a[i]) f[i] = max(f[i], f[j] + 1); } } int res = 0; for(int i = 1; i <= n; i++) { res = max(res, f[i]); } printf("%d", res); return 0; }
時間複雜度為\(O(n^2)\)