SGU 199 Beautiful People 二维最长递增子序列
题目链接:
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 + ; 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, -, sizeof(pre));
maxlen = ;
} int main() {
while (scanf("%d", &n) == && n) {
init();
for (int i = ; i < n; i++) {
scanf("%d%d", &arr[i].x, &arr[i].y);
arr[i].id = i + ;
}
sort(arr, arr + n);
dp[] = ; yy[++maxlen] = ;
for (int i = ; i < n; i++) {
int low = , hig = maxlen+;
if (arr[i].y <= arr[yy[low]].y) {
yy[low] = i;
continue;
}
while (low + < hig) {
int mid = low + (hig - low) / ;
if (arr[yy[mid]].y < arr[i].y) low = mid;
else hig = mid;
}
pre[i] = yy[low];
int len = low + ;
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 != -) {
ans.push_back(p);
p = pre[p];
}
printf("%d\n", ans.size());
for (int i = ; i < ans.size() - ; i++) printf("%d ", arr[ans[i]].id);
printf("%d\n", arr[ans[ans.size() - ]].id);
}
return ;
}
还有一种复杂的解决方法,用二分查找符合区间,然后用线段树查区间最大值。
待续。。。
SGU 199 Beautiful People 二维最长递增子序列的更多相关文章
- [poj1088]滑雪(二维最长下降子序列)
解题关键:记忆化搜索 #include<cstdio> #include<cstring> #include<algorithm> #include<cstd ...
- 最长公共子序列(LCS)和最长递增子序列(LIS)的求解
一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...
- LIS 最长递增子序列
一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...
- 华为OJ2288-合唱队(最长递增子序列)
一.题目描述 描述: N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, -, ...
- [SGU 199] Beautiful People
[SGU 199] Beautiful People The most prestigious sports club in one city has exactly N members. Each ...
- 二维动态规划&&二分查找的动态规划&&最长递增子序列&&最长连续递增子序列
题目描述与背景介绍 背景题目: [674. 最长连续递增序列]https://leetcode-cn.com/problems/longest-continuous-increasing-subseq ...
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...
- 最长递增子序列(Longest Increase Subsequence)
问题 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱).例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8 ...
- 51NOD 1376 最长递增子序列的数量 [CDQ分治]
1376 最长递增子序列的数量 首先可以用线段树优化$DP$做,转移时取$0...a[i]$的最大$f$值 但我要练习$CDQ$ $LIS$是二维偏序问题,偏序关系是$i<j,\ a_i< ...
随机推荐
- UITextView 光标定位
在使用UITextView的时候, 如何在光标的位置插入字符 或者 图片? 以下Demo为你解答: 应用背景:键盘自定义emoji表情 #pragma mark - KVO - (void)obser ...
- css动画Demo---水波动画和边框动画
先上效果图: 水波动画: 边框动画: 1.水波动画 实现代码 <!DOCTYPE html> <html lang="en"> <head> & ...
- redis学习指南
一.redis安装 # 安装最新版 yum install -y epel-release vim atop htop net-tools git wget gcc-c++ yum clean all ...
- Python学习 :多线程 --- 锁
多线程 什么是锁? - 锁通常被用来实现对共享资源的同步访问. - 为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁,则当前线 ...
- ubuntu软件安装
介绍常用的ubuntu软件及其安装 首先声明,本人在以下的操作全部基于腾讯云16.04版本ubuntu,若版本不一,有些出入,遇到问题可以在楼下留言. ubuntu中文官网 汉化终端 下载中文包 su ...
- python学习笔记(四):pandas基础
pandas 基础 serise import pandas as pd from pandas import Series, DataFrame obj = Series([4, -7, 5, 3] ...
- python的MetaClass的代码分析。基于廖雪峰博客代码
# 一张表一个类,表内每一行就是一个实例 ''' 一个单独的元类使用的程序分析. ''' class Field(object): def __init__(self, name, column_ty ...
- win10-MySql免安装版-安装/多实例
一.MySql免安装版安装: 1.MySql分为两个版本: 安装板的msi格式文件,直接点击下一步,下一步就可以安装 免安装版的zip格式,直接解压配置安装即可,[解压-初始化创建data目录-创建用 ...
- 变态的iis10
IIS10发布网站不能使用.NET4.0需要重新注册在之前版本的系统中使用如下命令可以直接重新注册: 但是windowsServer2016(iis 10) 使用该命令 提示 版本不支持 C:\WIN ...
- php S3调用SDK示例 AmazonS3
demo.php <?php /* * To change this license header, choose License Headers in Project Properties. ...