51nod1134(最长递增子序列)
2016-12-24 10:53
183 查看
题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1134
题意: 中文题诶~
思路: 直接暴力的话时间复杂度为O(n^2), 本题数据量为 5e4, 恐怕会超时;
我们维护当前最长的长度len, 用vis[j]存储长度为 j 的所有子序列中最小的末尾数值, 那么对于当前数据 a[i] , 如果数组vis中存在比其大的元素我们用a[i]替换掉vis中第一个比a[i]大的数, 若不存在,那么我们将a[i]加入 vis 末尾, 此时 vis 数组长度加一. 如此我们便维护了数组 vis 的性质, 最终得到的len就是答案了. 因为数组vis是递增的, 所以我们在查找时可以用二分(本人习惯用 upper_bound()), 那么时间复杂度便降为了 O(n*loglen).
代码:
题意: 中文题诶~
思路: 直接暴力的话时间复杂度为O(n^2), 本题数据量为 5e4, 恐怕会超时;
我们维护当前最长的长度len, 用vis[j]存储长度为 j 的所有子序列中最小的末尾数值, 那么对于当前数据 a[i] , 如果数组vis中存在比其大的元素我们用a[i]替换掉vis中第一个比a[i]大的数, 若不存在,那么我们将a[i]加入 vis 末尾, 此时 vis 数组长度加一. 如此我们便维护了数组 vis 的性质, 最终得到的len就是答案了. 因为数组vis是递增的, 所以我们在查找时可以用二分(本人习惯用 upper_bound()), 那么时间复杂度便降为了 O(n*loglen).
代码:
1 #include <bits/stdc++.h> 2 #define MAXN 50010 3 using namespace std; 4 5 const int MIN=-1e9; 6 7 int main(void){ 8 int n, a[MAXN], vis[MAXN], len=1; //vis[i]表示长度为i的数列中最小的末尾值 9 scanf("%d", &n); 10 for(int i=0; i<n; i++){ 11 scanf("%d", &a[i]); 12 } 13 for(int i=0; i<=n; i++){ 14 vis[i]=MIN; //注意本题数据范围是 -1e9~1e9 15 } 16 vis[1]=a[0]; 17 for(int i=1; i<n; i++){ 18 cout << endl; 19 int pos=upper_bound(vis+1, vis+len+1, a[i])-vis; 20 vis[pos]=a[i]; 21 if(len<pos){ //维护最大长度 22 len=pos; 23 } 24 } 25 printf("%d\n", len); 26 }
相关文章推荐
- 51 nod 1134 最长递增子序列
- Leetcode 300 Longest Increasing Subsequence 最长递增子序列
- HDU 1025 最长递增子序列
- 【面试题之算法部分】LIS最长递增子序列
- nyoj 17 数据结构 最长单调递增子序列
- 编辑距离,最长公共子序列,最长公共子串,最长递增子序列
- POJ 2533 最长递增子序列
- 用二分法寻找最长连续单调递增子序列
- 完美世界2016实习生笔试 [编程题] 最长递增子序列A(C++)
- poj 2127 Greatest Common Increasing Subsequence (最长公共递增子序列)
- 最长递增子序列
- 065_最长递增子序列
- NYOJ 17 最长单调递增子序列
- code vs [网络流24题] 最长递增子序列问题
- 最长递增子序列
- 编程之美-数组中最长递增子序列(包括输出)
- 动态规划算法之最长递增子序列问题
- 最长递增子序列问题
- 51nod1134 最长递增子序列
- 最长递增子序列