Gym 101246.H - “North-East” (二维LIS变形)
2017-10-16 20:34
441 查看
题意:给出n个点的坐标,现在有一个乐队,他可以从任一点出发,但是只能往右上方走(包括右方和上方),要经过尽量多的点。输出它可能经过的点和一定会经过的点。
思路:
如果按x轴从小到大,y轴从大到小排序,是不是等价于求y这一维度上的LIS。然后我们很快能处理出LIS,我们同时还需要记录一下,y[i]位于LIS中的长度len[i]。然后我们拿一个dpInv数组记录一下,dpInv[i]:长度为i的时候,当前最大长度是多少。只要y[i] < dpInv[len[i] + 1],是不是这个点就可以落在LIS上了,所有满足这个条件的点,就是maybe点。然后maybe点中,所有cnt[len[i]] == 1的点,是不是就一定要出现了,因为它意味着长度为len[i]的LIS的点的数量只有1个。就是must点。
思路:
如果按x轴从小到大,y轴从大到小排序,是不是等价于求y这一维度上的LIS。然后我们很快能处理出LIS,我们同时还需要记录一下,y[i]位于LIS中的长度len[i]。然后我们拿一个dpInv数组记录一下,dpInv[i]:长度为i的时候,当前最大长度是多少。只要y[i] < dpInv[len[i] + 1],是不是这个点就可以落在LIS上了,所有满足这个条件的点,就是maybe点。然后maybe点中,所有cnt[len[i]] == 1的点,是不是就一定要出现了,因为它意味着长度为len[i]的LIS的点的数量只有1个。就是must点。
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 5; const int INF = 0x3f3f3f3f; int dp[maxn], dpInv[maxn], len[maxn], cnt[maxn]; struct node{int x, y, id;}nodes[maxn]; int main() { freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); int n; scanf("%d", &n); for(int i = 1; i <= n; i++) { int x, y; scanf("%d%d", &x, &y); nodes[i] = {x, y, i}; } sort(nodes + 1, nodes + 1 + n, [](node a, node b) { if(a.x != b.x) return a.x < b.x; return a.y > b.y; }); memset(dp, INF, sizeof(dp)); for(int i = 1; i <= n; i++) { int pos = lower_bound(dp + 1, dp + 1 + n, nodes[i].y) - dp; dp[pos] = nodes[i].y; len[i] = pos; } memset(dpInv, -INF, sizeof(dpInv)); int totLen = lower_bound(dp + 1, dp + 1 + n, INF) - dp - 1; vector<int>vec; for(int i = n; i >= 1; i--) { int curLen = len[i]; if(curLen == totLen) { dpInv[curLen] = max(dpInv[curLen], nodes[i].y); cnt[curLen]++; vec.push_back(i); } else if(dpInv[curLen + 1] > nodes[i].y) { dpInv[curLen] = max(dpInv[curLen], nodes[i].y); cnt[curLen]++; vec.push_back(i); } } vector<int>maybe, must; for(auto o : vec) { maybe.push_back(nodes[o].id); if(cnt[len[o]] == 1) must.push_back(nodes[o].id); } sort(maybe.begin(), maybe.end()); printf("%d", maybe.size()); for(auto o : maybe) printf(" %d", o); puts(""); sort(must.begin(), must.end()); printf("%d", must.size()); for(auto o : must) printf(" %d", o); puts(""); return 0; }
相关文章推荐
- 【LIS】【递推】Gym - 101246H - ``North-East''
- SGU 521 North-East ( 二维LIS 线段树优化 )
- gym 100820G Racing Gems(二维LIS,好题)
- Gym-100820 Racing Gems(二维LIS)
- Gym 101196 (East Central North America Regional Contest 2016)
- Gym - 101246H ``North-East''【思维+nlogn LIS】
- Codeforces Gym 100379I Move the queen to the corner! 威佐夫博弈变形 + 高精度
- hdoj 5489 Removed Interval 【线段树维护LIS or LIS变形】
- Super Jumping! Jumping! Jumping!(hdu 1087 LIS变形)
- HDU 5256 序列变换 (LIS变形&&STL)
- hdu4521 线段树or变形LIS
- 计蒜客 The Heaviest Non-decreasing Subsequence Problem dp LIS变形 || 线段树+dp
- NBUT 1116 Flandre's Passageway (LIS变形)
- Gym 101246(ACM ICPC 2010-2011, NEERC, Southern Subregional Contest Russia, Saratov)
- jdfz-2764 二维LIS
- UVa 757 / POJ 1042 / East Central North America 1999 Gone Fishing (枚举&贪心&想法题&优先队列)
- Vawio Sequence (NYOJ 763 LIS变形)
- 九度 1500:出操队形(LIS变形)
- HDU 5773 DP LIS变形
- HDU5773 The All-purpose Zero(LIS变形)