最长上升子序列
Description
求最长上升子序列。
Input
单测试用例。
第一行是一个正整数n,0 < n ≤ 3000
第二行是n个非负整数。
Output
两行结果。
第一行是最长上升子序列的长度。
第二行是任意一个最长上升子序列,每个整数后面跟一个空格。
Sample Input
8
5 2 8 6 3 6 9 7
Sample Output
4
2 3 6 7
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int maxn = 3e3 + 10; int n, len, en, squ[maxn], dp[maxn], pre[maxn]; void so() { len = en = 1; dp[1] = 1; for(int i=2; i<=n; i++){ dp[i] = 1; for(int j=1; j<i; j++){ if(squ[j] < squ[i] && dp[j]+1 > dp[i]){ dp[i] = dp[j]+1; pre[i] = j; } } if(dp[i] > len){ len = dp[i]; en = i; } } } int main(void) { scanf("%d", &n); for(int i=1; i<=n; i++){ scanf("%d", &squ[i]); pre[i] = i; } so(); printf("%d\n", len); stack<int> res; while(pre[en] != en){ res.push(squ[en]); en = pre[en]; } printf("%d ", squ[en]); while(!res.empty()){ printf("%d ", res.top()); res.pop(); }puts(""); return 0; }
求一个序列中每次都删除最长的单调序列,要进行多少轮
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; int main(){ int i=1,ans=-1,s=-1,a[1010],dp[1010],sys[1010]; while(cin>>a[i]){ dp[i]=sys[i]=1; for(int j=i-1;j>=1;j--) if (a[j]>=a[i]) dp[i]=max(dp[j]+1,dp[i]); else if (a[j]<a[i]) sys[i]=max(sys[j]+1,sys[i]); ans=max(ans,dp[i]); s=max(s,sys[i]); i++; } cout<<ans<<endl<<s<<endl;; return 0; }
S是答案