ZOJ - 2319 Beautiful People 【最长单调递增子序列变形】
2017-04-18 18:01
831 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2319
比赛链接:https://cn.vjudge.net/contest/158741#overview 密码:nyist
题目大意:首先输入一个数n,接下来是n行,每行两个数分别是Si、Bi;找尽可能多的人使他们不相互讨厌;
分析:相互讨厌:(Si<=Sj&&Bi>=Bj)or(Si>=Sj&&Bi<=Bj)根据这个条件,我们可以推断出当Si<Sj&&Bi<Bj时,满足这个条件找出的人才不相互讨厌。
那么要怎么找呢???是不是特别像最长单调递增子序列,就是这样。我们可以预处理一下(按Si从小到大排序,Bi从大到小排序),处理之后左端点就是单调递增的,这样我们找的时候就不用管了,在右端点中找最长单调递增子序列,找出来的结果就是我们要求的。
比赛的时候想到了最长单调递增子序列,但我们一直在想两个值同时递增怎么处理,虽然也排序预处理了,但还是没有想到直接找一个端点就行了。。。
Code:
比赛链接:https://cn.vjudge.net/contest/158741#overview 密码:nyist
题目大意:首先输入一个数n,接下来是n行,每行两个数分别是Si、Bi;找尽可能多的人使他们不相互讨厌;
分析:相互讨厌:(Si<=Sj&&Bi>=Bj)or(Si>=Sj&&Bi<=Bj)根据这个条件,我们可以推断出当Si<Sj&&Bi<Bj时,满足这个条件找出的人才不相互讨厌。
那么要怎么找呢???是不是特别像最长单调递增子序列,就是这样。我们可以预处理一下(按Si从小到大排序,Bi从大到小排序),处理之后左端点就是单调递增的,这样我们找的时候就不用管了,在右端点中找最长单调递增子序列,找出来的结果就是我们要求的。
比赛的时候想到了最长单调递增子序列,但我们一直在想两个值同时递增怎么处理,虽然也排序预处理了,但还是没有想到直接找一个端点就行了。。。
Code:
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<stdlib.h> #include<queue> using namespace std; const int maxn=100100; struct node { int x,y,id; } c[maxn]; bool cmp(node aa,node bb) { if(aa.x==bb.x) return aa.y>bb.y; else return aa.x<bb.x; } int dp[maxn],ans[maxn],flag[maxn]; int main() { int t,n,T=0; scanf("%d",&t); while(t--) { if(T++) printf("\n"); memset(ans,0,sizeof(ans)); memset(flag,0,sizeof(flag)); memset(dp,0,sizeof(dp)); scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d%d",&c[i].x,&c[i].y); c[i].id=i+1; } sort(c,c+n,cmp); int len=0; dp[++len]=c[0].y; ans[0]=len; for(int i=1; i<n; i++) { // cout<<len<<endl; if(dp[len]<c[i].y) { // printf("%d***\n",c[i].y); dp[++len]=c[i].y; ans[i]=len; } else { int pos=lower_bound(dp+1,dp+len+1,c[i].y)-dp; //二分右端点,找出c[i].y在dp数组中要更新的位置,并更新 //cout<<c[i].y<<" pos="<<pos<<endl; dp[pos]=c[i].y; ans[i]=pos;//记录当前点i属于上升子序列的第几个 } } int k=0; printf("%d\n",len); for(int i=n-1; i>=0; i--) { if(ans[i]==len) { //flag[k++]=ans[i]; flag[k++]=c[i].id; len--; if(!len) break; } // printf("%d ",ans[i]); } sort(flag,flag+k); for(int i=0;i<k;i++) { if(i) printf(" "); printf("%d",flag[i]); } printf("\n"); } }
相关文章推荐
- ZOJ 2319 Beatuiful People(单调递增序列的变形)
- ZOJ 2319【二维最长递增子序列】
- Beautiful People ZOJ - 2319(单调递增最长子序列)
- Beautiful People ZOJ - 2319(单调递增子序列,记录路径)
- 【第四场省赛组队赛训练补题】ZOJ - 2319 Beautiful People (最长单调递增子序列 O(nlogn) )
- Beautiful People (最长单调递增子序列(变形))
- hdu 1257 最少拦截系统(最长单调递增序列)
- nyoj241 最长单调递增子序列二
- NYOJ - 814 - 又见拦截导弹(动态规划--最大单调递增子序列变形)
- 最长单调递增子序列的求法
- POJ 1836 Alignment 最长递增子序列(LIS)的变形
- 矩形嵌套--动态规划--最长递增子序列问题变形
- 最长单调递增子序列(二分查找优化)
- 最长单调递增子序列( O(nlgn) )
- 设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
- hdu 1069 Monkey and Banana 动态规划(最长递增子序列变形)
- 最长单调递增子序列-LIS问题
- NYOJ - 79 - 拦截导弹(动态规划--LIS--最长递增子序列变形)
- ZOJ 2319 Beatuiful People(单调上升子序列变形)
- poj 1952 BUY LOW, BUY LOWER[最长单调子序列变形]