您的位置:首页 > 运维架构

ZOJ 2319 Beautiful People (LIS的变形)

2015-10-08 20:06 435 查看

题目大意

有n个人的,每个人有一个si和bi,对于i和j来说,只有当si < sj && bi < bj ,或者 si > sj && bi > bj 时,二人才不会互相讨厌。

也就是说,只有两个人其中一方的s和b都小于另一方时,二人才不会互相讨厌。

求最多有多少人不会互相讨厌

分析

给n个人按s排序从小到大,若s相等则按b从大到小排序。

然后求b的最长上升子序列的长度ans即可

用O(nlogn)的算法

最后再按照ans构造路径

代码

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
#define INF 0x7fffffff
const int maxn = 1e5+10;
struct Node {
int s , b;
int id;
bool operator < (const Node &rhs) const {
return (s < rhs.s) || (s == rhs.s && b > rhs.b);
}
}node[maxn];
int dp[maxn]; //dp[i]表示以i结尾的最长上升子序列的长度
int g[maxn];  //g[i]表示dp值为i的最小状态值
int rel[maxn];

int main()
{
int t , n;
cin >> t;
while(t--)
{
cin >> n;
for(int i = 0; i < n; i++) {
cin >> node[i].s >> node[i].b;
node[i].id = i + 1;
}
sort(node , node + n);
for(int i = 1; i <= n; i++) g[i] = INF;

for(int i = 0; i < n; i++) {
int k = lower_bound(g+1 , g+1+n , node[i].b) - g;
dp[i] = k;
g[k] = node[i].b;
}

int ans = dp[0] , cnt = 0;;
for(int i = 1; i < n; i++) ans = max(ans , dp[i]);
cout << ans << endl;
for(int i = n-1; i >= 0; i--) if(ans == dp[i]) {
rel[cnt++] = node[i].id;
ans--;
}
for(int i = cnt - 1; i > 0; i--) cout << rel[i] << " ";
cout << rel[0] << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: