http://codeforces.com/gym/101246/problem/H

题意:在二维平面上有n个点,从最左下角的点出发,每次走只能走在当前的点的右上角的点(xj > xi, yj > yi)。问在走了最长路径的前提下有哪些点是可能被走到的,哪些点是必须被走到的。

思路:比赛的时候以为是图论的题目,结果可以转化为LIS求解,太强啦。

首先直接对坐标按照x从小到大进行排序,如果x相同,y从大到小排序。为什么y是从大到小排序呢?因为在后面我们只看y的大小来做LIS,即通过排序消掉了x维,那么如果x相同的话,y小的在前面会使长度变大,但是此时的x是相同的,并不满足题意要严格在右上角的要求,如果y大的在前面就不会使得长度变长了。因此是从大到小排序。

做LIS,是为了得到一个数组:h[i]代表i这个点的LIS的长度是多少。这样就可以直接求解了。观察下面这样一个样例。

(每次画图都是画得很恶心)

我们知道,假设要从3走到4,那么3的y必须严格小于后面的4的y的,否则这个点是不可能走的。

这样我们看图中,7、8两点的4肯定是由6号点的3贡献的,因为4、5号点的3的y是大于等于后面所有的4的。

这样我们可以逆向思维,从后往前扫,对于每个LIS的长度维护一个最大的y值,用一个maxh[]数组表示。设求得LIS最长长度为len,长度为len的所有点都可能走到,当扫到长度为len-1的时候,只有yi是小于maxh[len]才有可能走到,就这样扫到1。

还要解决哪些点必须走到,其实就是在可能走到的点里面,长度为h的点有且仅有一个的时候,这个点就必须走到,因为如果不走过这个点,就无法到达下一个长度为h+1的点了。

 #include <bits/stdc++.h>
using namespace std;
#define N 100010
struct node {
int x, y, id;
} p[N];
int n, len, h[N], maxh[N], dp[N], Hash[N];
vector<int> maybe, must; bool cmp(const node &a, const node &b) { if(a.x == b.x) return a.y > b.y; return a.x < b.x; } bool cp(const int &a, const int &b) { return p[a].id < p[b].id; } void LIS() { // 求解LIS
sort(p + , p + + n, cmp);
dp[] = p[].y; h[] = len = ;
for(int i = ; i <= n; i++) {
if(p[i].y > dp[len]) { dp[++len] = p[i].y; h[i] = len; }
int tmp = lower_bound(dp + , dp + + len, p[i].y) - dp;
dp[tmp] = p[i].y; h[i] = tmp;
}
} void solve() {
// 处理出哪些是可能的
for(int i = ; i <= n; i++) maxh[i] = -;
for(int i = n; i >= ; i--)
if(h[i] == len) { maxh[h[i]] = max(maxh[h[i]], p[i].y); maybe.push_back(i); }
else if(maxh[h[i]+] > p[i].y) { maxh[h[i]] = max(maxh[h[i]], p[i].y); maybe.push_back(i); }
// 处理出哪些是必须的
for(int i = ; i < maybe.size(); i++) Hash[h[maybe[i]]]++;
for(int i = ; i < maybe.size(); i++)
if(Hash[h[maybe[i]]] == ) must.push_back(maybe[i]); sort(maybe.begin(), maybe.end(), cp);
sort(must.begin(), must.end(), cp);
printf("%d ", maybe.size());
for(int i = ; i < maybe.size(); i++) printf("%d ", p[maybe[i]].id); puts("");
printf("%d ", must.size());
for(int i = ; i < must.size(); i++) printf("%d ", p[must[i]].id); puts("");
} int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
scanf("%d", &n);
for(int i = ; i <= n; i++) scanf("%d%d", &p[i].x, &p[i].y), p[i].id = i;
LIS();
solve();
return ;
}

Codeforces Gym101246H:``North-East''(LIS+思维)的更多相关文章

  1. Codeforces 583D. Once Again... (LIS变形)

    题目链接:http://codeforces.com/contest/583/problem/D 给你t个长度为n的数组.问你最长不下降子序列的长度. 一开始用第一个n数组的lis和最后一个n数组的l ...

  2. Codeforces Zip-line 650D 345Div1D(LIS)

    传送门 大意:给出一个序列,求修改一个数过后的最长上升子序列. 思路:可以用主席树在线搞,也可以用树状数组离线搞,明显后者好写得多.我们首先读取所有的询问,然后就把询问绑在给出的位置,然后我们正向做一 ...

  3. CodeForces - 427A (警察和罪犯 思维题)

    Police Recruits Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Sub ...

  4. codeforces 895B XK Segments 二分 思维

    codeforces 895B XK Segments 题目大意: 寻找符合要求的\((i,j)\)对,有:\[a_i \le a_j \] 同时存在\(k\),且\(k\)能够被\(x\)整除,\( ...

  5. codeforces 893D Credit Card 贪心 思维

    codeforces 893D Credit Card 题目大意: 有一张信用卡可以使用,每天白天都可以去给卡充钱.到了晚上,进入银行对卡的操作时间,操作有三种: 1.\(a_i>0\) 银行会 ...

  6. C. Nice Garland Codeforces Round #535 (Div. 3) 思维题

    C. Nice Garland time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  7. hdu5256 二分求LIS+思维

    解题的思路很巧,为了让每个数之间都留出对应的上升空间,使a[i]=a[i]-i,然后再求LIS 另外二分求LIS是比较快的 #include<bits/stdc++.h> #define ...

  8. C Alyona and Spreadsheet Codeforces Round #401(Div. 2)(思维)

    Alyona and Spreadsheet 这就是一道思维的题,谈不上算法什么的,但我当时就是不会,直到别人告诉了我,我才懂了的.唉 为什么总是这么弱呢? [题目链接]Alyona and Spre ...

  9. codeforces 848B Rooter's Song 思维题

    http://codeforces.com/problemset/problem/848/B 给定一个二维坐标系,点从横轴或纵轴垂直于发射的坐标轴射入(0,0)-(w,h)的矩形空间.给出点发射的坐标 ...

随机推荐

  1. springmvc 与 springfox-swagger2整合

    一.pom.xml引入基于maven的swagger依赖 <dependency> <groupId>io.springfox</groupId> <arti ...

  2. sql server DateTime与DateTime2的区别

    DateTime字段类型对应的时间格式是 yyyy-MM-dd HH:mm:ss.fff ,3个f,精确到1毫秒(ms),示例 2014-12-03 17:06:15.433 .DateTime2字段 ...

  3. JS 小鸟飞

    <!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  4. 待修 Bug

    # 乱码 ## 描述 环境:Tomcat 8 + Spring 4 + Spring Security. 问题描述: 在类 AbstractAnnotationConfigDispatcherServ ...

  5. [Windows][VC]开机自动启动程序的几种方法

    原文:[Windows][VC]开机自动启动程序的几种方法 很多监控软件要求软件能够在系统重新启动后不用用户去点击图标启动项目,而是直接能够启动运行,方法是写注册表Software\\Microsof ...

  6. 如果你说最近在看《诛仙》,平时喜欢玩LOL,你就是在把自己往悬崖上推

    面试官可能会问你一些和技术看上去没有任何关系的问题,比如问你最近在看什么书,学习之余喜欢做什么,常去哪些网站之类的.如果你说最近在看<诛仙>,平时喜欢玩LOL,你就是在把自己往悬崖上推.实 ...

  7. mariadb 允许远程访问

    进入MariaDB服务器,将mysql.user的host字段的值改为%就表示在任何客户端机器上能以root用户登录到mysql服务器,建议在开发时设为%. 1 MariaDB [(none)]> ...

  8. 图像滤镜艺术---LOMO Filter

    原文:图像滤镜艺术---LOMO Filter LOMO Filter LOMO是一种概念,即强调感受.机缘,弱化摄影技巧,不确定性和随意性是LOMO最大特点.LOMO源于Lomography,LOM ...

  9. HTML5离线缓存攻击测试

    本实验采用局域网模拟,通过修改本地HOSTS文件来模拟域名以及DNS欺骗.合法网站使用Linux CentOS7的apache服务器搭建,IP为192.168.1.113,HOSTS文件中加入192. ...

  10. 微信小程序把玩(二十二)action-sheet组件

    原文:微信小程序把玩(二十二)action-sheet组件 action-sheet组件是从底部弹出可选菜单项,估计也是借鉴IOS的设计添加的,action-sheet有两个子组件, action-s ...