SGU 199 Beautiful People 二维最长递增子序列
2016-05-07 01:50
381 查看
题目链接:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20885题意:
求二维最长严格递增子序列。题解:
O(n^2)的算法很好想,不过这里会t掉,只能O(nlogn)于是用二分来维护:
先把所有的数按x递增排序,x相同的按y递减排序(这里之所以要按y递减排序是因为为了写代码方便,递减的话你后面基本就只要考虑y的大小,如果不递减,你还要考虑x的大小的,具体的可以自己思考一下)
排完序之后我们接下来就只考虑y的大小,我们维护一个目前长度为len的最长子序列,并且它的value取目前所有长度为len的最长子序列中,以最小y结尾的那个y值。
然后我们会发现我们维护的这些长度的value是随长度变大递增的!!!(这个可以证明!),于是就可以用二分来找能接在当前的那个人后面的最长的长度。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int maxn = 1e5 + 10; struct Node { int x, y,id; bool operator < (const Node& tmp) const { return x < tmp.x||x==tmp.x&&y>tmp.y; } }arr[maxn]; int n,maxlen; int pre[maxn],dp[maxn],yy[maxn]; void init() { memset(pre, -1, sizeof(pre)); maxlen = 0; } int main() { while (scanf("%d", &n) == 1 && n) { init(); for (int i = 0; i < n; i++) { scanf("%d%d", &arr[i].x, &arr[i].y); arr[i].id = i + 1; } sort(arr, arr + n); dp[0] = 1; yy[++maxlen] = 0; for (int i = 1; i < n; i++) { int low = 1, hig = maxlen+1; if (arr[i].y <= arr[yy[low]].y) { yy[low] = i; continue; } while (low + 1 < hig) { int mid = low + (hig - low) / 2; if (arr[yy[mid]].y < arr[i].y) low = mid; else hig = mid; } pre[i] = yy[low]; int len = low + 1; if (len > maxlen) { yy[++maxlen] = i; } else { if (arr[i].y < arr[yy[len]].y) yy[len] = i; } } vector<int> ans; int p = yy[maxlen]; while (p != -1) { ans.push_back(p); p = pre[p]; } printf("%d\n", ans.size()); for (int i = 0; i < ans.size() - 1; i++) printf("%d ", arr[ans[i]].id); printf("%d\n", arr[ans[ans.size() - 1]].id); } return 0; }
还有一种复杂的解决方法,用二分查找符合区间,然后用线段树查区间最大值。
待续。。。
相关文章推荐
- Android视图控件架构分析之View、ViewGroup
- [Architecture] 系统架构正交分解法
- 【译】Android系统架构
- CentOS7上安装Pycharm
- OpenGLES:: GLKView是如何工作的
- 解决linux不能解压rar格式压缩包
- popupWindow (弹出窗口)点击某个按钮时,在旁边显示其他按钮。
- org.apache.commons.lang3.xwork.StringUtils找不到的问题
- linux平台使用gnu工具链来开发stm32单片机 环境搭建,备忘录
- CProperySheet使用
- if top实时监控参考
- 2016学习Linux决心书
- 一个可以查看 Linux 当前缓存了哪些大文件的小工具
- CentOS下搭建PHP环境与WordPress博客程序的全流程总结
- linux安装jdk详细步骤(rpm方式)
- how to custom bash prompt
- 开启Nginx的目录文件列表功能
- linux rsync+inotify 文件自动同步
- runloop
- Apache漏洞修复