sgu199:Beautiful People(最长上升子序列)

来源:互联网 发布:湖南大学829c语言真题 编辑:程序博客网 时间:2024/05/16 09:32

题意:

告诉你有n个人,以及每个人的力量和美丽的程度值(我记录为x,y),并依次记录他们的id为1~n。用两个人(i和j)比较,p[i].x > p[j].x && p[i].y 
p[j].y 和 p[i].x < p[j].x && p[i].y < p[j].y 说明同时邀请这两人,他们就不会闹事,其余情况(p[i].x <= p[j].x && p[i].y >= p[j].y 和 p[i].x >= 

p[j].x && p[i].y <= p[j].y)说明同时邀请他们就会出事,问最多可以邀请多少人,并且保证这些人不会闹事?

数据范围:2<=n<=10,000;1<=x,y<= 10^9;

分析:

按s为第一关键字,b为第二关键字,s递增,b递减,排序后, 做nlogn的最长上升子序列就好。

#include <cstdio>#include <algorithm>using namespace std;const int MAXN = 100009;int n;struct people{int s, b, i;void read() {scanf("%d%d", &s, &b);}}inv[MAXN];int minf[MAXN];int f[MAXN], pre[MAXN];int ans, MAX;int out[MAXN], top;bool cmp(const people a, const people b) {return a.s<b.s || (a.s==b.s && a.b>b.b);}int binary(int lim){int l = 0, r = MAX;while(l < r){int mid = (l+r)>>1;if(inv[minf[mid]].b < lim && inv[minf[mid+1]].b >= lim) return minf[mid];else if(inv[minf[mid]].b < lim) l = mid+1;else r = mid;  }return minf[l];}int main(){scanf("%d", &n);for(int i = 1; i <= n; ++i){inv[i].read();inv[i].i = i;}sort(inv+1, inv+n+1, cmp);for(int i = 1; i <= n; ++i){int k = binary(inv[i].b);pre[i] = k;f[i] = f[k]+1;if(f[i] > MAX) {MAX = f[i];ans = i;}if(!minf[f[i]] || inv[minf[f[i]]].b > inv[i].b) minf[f[i]] = i;}printf("%d\n", MAX);for(int i = ans; i; i = pre[i]) out[++top] = inv[i].i;sort(out+1, out+top+1);printf("%d", out[1]);for(int i = 2; i <= top; ++i)printf(" %d", out[i]);printf("\n");return 0;}


0 0
原创粉丝点击