Beautiful People
Problem Description
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 prestige 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
Output
Sample Input
4 1 1 1 2 2 1 2 2
Sample Output
2 1 4
网上看到的神解法, 这道题不同与一般的LIS, 这道题是可以排序的, 反而和嵌套模型和像, 但是嵌套模型的做法复杂度是O(n*n)。
其实这道题的方法就是贪心。
重点就如何排序, 先按第一权重排序(从小到大), 然后按第二权重排序(从大到小)。
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <functional>
#include <cstring>
#define UFOR(i, a, b) for(int i = (int)a; i <= (int)b; i++)
#define DFOR(i, a, b) for(int i = (int)a; i >= (int)b; i--)
#define MEM0(a) memset(a, 0, sizeof(a))
#define MEM1(a) memset(a, -1, sizeof(a))
#define MEMINF(a) memset(a, 0x3f3f3f3f, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define FIN freopen("in.txt", "r", stdin)
#define FOUT freopen("out.txt", "w", stdout)
using namespace std;
//typedef __int64 LL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int MXN = 1e5 + 10;
const int MXM = 13521;
const int HS = 1000007;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
struct A {
int l, r, id;
bool operator < (const A& X) const {
return l < X.l || (l == X.l && r > X.r);
}
} a[MXN];
int dp[MXN], mark[MXN];
int main ()
{
int n;
while (~scanf("%d", &n)) {
MEMINF(dp);
MEM0(mark);
UFOR (i, 1, n) {
scanf("%d %d", &a[i].l, &a[i].r);
a[i].id = i;
}
sort(a + 1, a + n + 1);
int cnt = 1, ans = 0;
UFOR (i, 1, n) {
int id = lower_bound(dp + 1, dp + cnt + 1, a[i].r) - dp; //cnt 只是为了减少复杂度而已
if (id == cnt) cnt++;
dp[id] = a[i].r;
mark[i] = id;
ans = max(ans, id);
}
printf("%d\n", ans);
DFOR (i, n, 1) { // 必须倒着输出, 这样才是答案, 正着输出是错误的 (仔细想想)
if (mark[i] == ans) {
printf("%d%c", a[i].id, (ans == 1 ? '\n' : ' '));
ans--;
}
}
}
return 0;
}