SGU 199. Beautiful People(最长上升子序列nlogn LIS)
2017-10-16 18:01
288 查看
Problem Statement
The most prestigious sports club in one city has exactly N members. Each of its members is strong and beautiful. More precisely, i-th member of this club (members being numbered by the time they entered the club) has strength Si and beauty Bi . Since this is a very prestigious club, its members are very rich and therefore extraordinary people, so they often extremely hate each other. Strictly speaking, i-th member of the club Mr X hates j-th member of the club Mr Y if Si ≤ Sj and Bi ≥ Bj or if Si ≥ Sj and Bi ≤ Bj (if both properties of Mr X are greater then corresponding properties of Mr Y, he doesn’t even notice him, on the other hand, if both of his properties are less, he respects Mr Y very much).To celebrate a new 2003 year, the administration of the club is planning to organize a party. However they are afraid that if two people who hate each other would simultaneouly attend the party, after a drink or two they would start a fight. So no two people who hate each other should be invited. On the other hand, to keep the club presti≥ at the apropriate level, administration wants to invite as many people as possible.
Being the only one among administration who is not afraid of touching a computer, you are to write a program which would find out whom to invite to the party.
Input
The first line of the input file contains integer N — the number of members of the club. ( 2 ≤ N ≤ 100,000 ). Next N lines contain two numbers each — Si and Bi respectively ( 1 ≤ Si, Bi ≤ 109 ).Output
On the first line of the output file print the maximum number of the people that can be invited to the party. On the second line output N integers — numbers of members to be invited in arbitrary order. If several solutions exist, output any one.Example
Input4
1 1
1 2
2 1
2 2
Output
2
1 4
题意
一个俱乐部里一共有n个人,每个人有两个值,力量S和美丽B,让你求出一组人,使得这一组人里面对于每个人i,1<i<=n,Si>Si−1 and Bi>Bi−1,并且人数要最多。简单说就是要求一个二维最长上升子序列。思路
首先由题意得,这题要求的是二维的最长上升子序列,而根据数据范围来看,还是要nlogn的,如果两维一起做的话大概是不可行的,而两维分开做,求出的最长上升子序列又有很大可能是不一样的。所以我们有这样一种想法,对于所有人我们先排序,将S从小到大排序并将S相等的人将B从大到小排序,这样我们就可以只用对B这一维进行最长上升子序列了。因为这样排序的话,S相等的,B最大的都在最前面,后面的不会影响。还有,这题需要打印一组可行的解,我们对于每一位,记录一个pre,表示这一位的前面符合的第一个是哪一位,最后只要递归打印就可以出解了。Code
#pragma GCC optimize(3) #include<bits/stdc++.h> using namespace std; typedef long long ll; inline void readInt(int &x) { x=0;int f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); x*=f; } inline void readLong(ll &x) { x=0;int f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); x*=f; } /*================Header Template==============*/ const ll base=1e9; ll x[100010],idx[100010]; int n,len,pre[100010]; struct peo{ll x,y;int id;}p[100010]; inline bool cmp(peo a,peo b){return a.x==b.x?a.y>b.y:a.x<b.x;} inline void print(int ans) { if(ans==0) return; print(pre[ans]); printf("%d",p[ans].id); putchar(x[len]==ans?'\n':' '); } int main() { readInt(n); for(int i=1;i<=n;i++) { p[i].id=i; readLong(p[i].x); readLong(p[i].y); } sort(p+1,p+n+1,cmp); x[1]=1; int len=1; for(int i=2;i<=n;i++) { int l=1,r=len; while(l<=r) { int mid=(l+r)>>1; if(p[x[mid]].y<p[i].y) l=mid+1; else r=mid-1; } x[l]=i; pre[i]=x[l-1]; len=max(len,l); } printf("%d\n",len); print(x[len]); return 0; }
相关文章推荐
- SGU 199 - Beautiful People 最长上升子序列LIS
- SGU 199 Beautiful People(最长上升子序列)
- SGU 199 Beautiful People 二维最长递增子序列
- SGU - 199(最长不下降子序列)
- 最长上升子序列问题的几种解法
- LIS最长上升子序列O(n^2)&O(nlogn)
- hdu 1160 dp (二维最长上升子序列 记录路径
- HDU 1087 最长上升子序列
- 最长上升子序列LIS O(nlgn)算法
- poj 2533 Longest Ordered Subsequence (DP:最长上升子序列)
- HDU 3308 LCIS(最长连续上升子序列)
- POJ2533(最长上升子序列)
- 最长上升子序列问题总结
- POJ 1631 Bridging signals DP(最长上升子序列)
- LintCode算法题解——岛屿个数、有效回文串、最长上升子序列
- 动态规划-再次理解最长上升子序列
- 最长上升子序列(非连续)
- bzoj 3173: [Tjoi2013]最长上升子序列
- UVA 10154 Weights and Measures(贪心+DP最长上升子序列)
- CodeForces 10D. LCIS 最长公共上升子序列模板题 + 打印路径