Book--LIS 及其输出解 浅析
2015-06-04 00:08:21
总结:之前就想过的一个问题,直到今天被学弟问到才重新开始想。
看了:http://m.blog.csdn.net/blog/u013654731/27801843
感觉 nlogn 的做法也是可以记录路径的(当然这种方法只能记录一条路径)
具体想法:在 nlogn 的做法中,每往队列中插入一个数,就保存其在队列中的位置(即 pos[] 数组),然后就获得了数列中所有数的pos值,以及LIS长度len,
最后从后面往前面扫,先找pos值为len的数,再找pos值为len-1的数... 以此类推就获得了一串 LIS。
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #include <string> #include <iostream> #include <algorithm> using namespace std; #define getmid(l,r) ((l) + ((r) - (l)) / 2) #define MP(a,b) make_pair(a,b) #define PB(a) push_back(a) typedef long long ll; typedef pair<int,int> pii; const double eps = 1e-8; const int INF = (1 << 30) - 1; const int MAXN = 10100; int n; int A[MAXN]; int Q[MAXN],len; int pos[MAXN]; int ans[MAXN]; int main(){ while(scanf("%d",&n) != EOF){ for(int i = 1; i <= n; ++i) scanf("%d",A + i); len = 0; for(int i = 1; i <= n; ++i){ int p = lower_bound(Q + 1,Q + len + 1,A[i]) - Q; Q[p] = A[i]; pos[i] = p; if(p > len) len++; } int cur = len; for(int i = n; i >= 1; --i){ if(pos[i] == cur){ ans[cur] = A[i]; --cur; } if(cur <= 0) break; } bool flag = true; for(int i = 1; i < len; ++i) if(ans[i] >= ans[i + 1]){ flag = false; break; } if(!flag) printf("Oh no!\n"); else printf("Yes"); } return 0; }