动态规划 最长上升子序列 LIS-
(1) O(n^2) 动态规划
(2) O(nlogn) 二分做法
(1) 动态规划做法:
#include <iostream> #include <cstring> using namespace std; int dp[101],a[101],n; int LIS(){ int ans = 0; for(int i=1;i<=n;i++){ dp[i] = 1; for(int j=1;j<i;j++){ if(a[j] < a[i]){ dp[i] = max(dp[i],dp[j] + 1); } } ans = max(ans,dp[i]); } return ans; } int main() { cin >> n; for(int i=1;i<=n;i++){ cin >> a[i]; } cout << LIS() << endl; return 0; }
(2) 二分搜索
#include <iostream> #include <algorithm> using namespace std; const int MAXN = 1e4; int a[MAXN]; int d[MAXN]; const int INF = 0x3f3f3f3f; int main(){ ios::sync_with_stdio(false); int n; while(cin >> n && n){ int cnt = 0; d[0] = 0;//哨兵 for(int i=0;i<n;++i){ cin >> a[i]; if(d[cnt] < a[i]){ d[++cnt] = a[i]; }else{ int pos = upper_bound(d,d+cnt,a[i]) - d; d[pos] = a[i]; } } cout << cnt << endl; } return 0; }
题目:
题解:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <iostream> #include <algorithm> using namespace std; int a[1001]; int dp [1001]; const int INF = 0x3f3f3f3f; int main(){ int n; while(cin >> n&& n){ for(int i=0;i<n;++i){ cin >> a[i]; } for(int i=0;i<n;++i){ dp[i] = a[i]; for(int j=0;j<i;++j){ if(a[i] > a[j]){ dp[i] = max(dp[j] + a[i],dp[i]); } } } int maxN = a[0]; for(int i=0;i<n;++i){ maxN = max(maxN,dp[i]); } cout << maxN << endl; } return 0; }