题意:一个人有两个属性S, B(1 ≤ Si, Bi ≤ 10^9),当两个人的这两个属性满足 S1 < S2 && B1 < B2 或者 S1 > S2 && B1 > B2 时,这两个人不会讨厌对方。现给出 N 个人(2 ≤ N ≤ 100 000)的属性,求最多能有多少个人,他们之间任意两人都不会讨厌对方。
题目链接:http://acdream.info/problem?pid=1216
——>>容易想到是一个二维的LIS模型。。
二维降一维,控制其中一维递增,对另一维求LIS。。(主要是在排序的时候,让第一维从小到大排,第二维从大到小排,那么,排序后对第二维求LIS的结果肯定不会出现其中的元素对应的第一维是相同的,因为相同的第一维对应的第二维是递减的,而对第二维求LIS是严格递增的。。)
#include <cstdio>
#include <algorithm>
#include <cstring>using std::sort;
using std::lower_bound;const int MAXN = 100000 + 10;
const int INF = 0x3f3f3f3f;struct PERSON
{int id;int S;int B;bool operator < (const PERSON& e) const{return S < e.S || (S == e.S && B > e.B);}
} person[MAXN];int N;
int buf[MAXN];
int lis[MAXN], who[MAXN], fa[MAXN], cnt;int LIS()
{int ret = 1;memset(lis, 0x3f, sizeof(lis));memset(fa, -1, sizeof(fa));who[0] = -1;for (int i = 1; i <= N; ++i){int id = lower_bound(lis + 1, lis + 1 + N, buf[i]) - lis;lis[id] = buf[i];who[id] = i;fa[i] = who[id - 1];if (id > ret){ret = id;}}return ret;
}void Read()
{for (int i = 1; i <= N; ++i){scanf("%d%d", &person[i].S, &person[i].B);person[i].id = i;}
}void Init()
{sort(person + 1, person + 1 + N);for (int i = 1; i <= N; ++i){buf[i] = person[i].B;}
}void Output(int x)
{if (fa[x] == -1){printf("%d", person[x].id);return;}Output(fa[x]);printf(" %d", person[x].id);
}void Solve()
{cnt = LIS();printf("%d\n", cnt);Output(who[cnt]);puts("");
}int main()
{while (scanf("%d", &N) == 1){Read();Init();Solve();}return 0;
}