1. 思路
对于LIS的求解问题,我采用的是二分+贪心进行求解,然后对于打印路径采用一个f[]数组记录,f[i]代表LIS序列中的第i个元素的前面的一个元素的位置;
2. code
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
const int N = 1e5+5;
int val[N], dp[N], f[N], pos[N];
int main() {
int n = 0;
int m;
while(scanf("%d", &m) != EOF) {
val[n++] = m;
}
memset(dp, 0x3f3f3f3f, sizeof(dp));
// dp[0] = 0;
for(int i = 0; i < n; ++ i) {
int lpos = lower_bound(dp, dp+n, val[i]) - dp; //在已构造的LIS序列中找出大于等于val[i]的元素的位置
dp[lpos] = val[i];
pos[lpos] = i;
f[i] = (lpos ? pos[lpos-1] : -1); // 记录路径
}
stack<int> s;
n = lower_bound(dp, dp+n, 0x3f3f3f3f) - dp;
printf("%d\n-\n", n);
for(int i = pos[n-1]; i != -1; i = f[i]) { // 从LIS序列的最后一个元素向前回溯
s.push(val[i]);
}
while(!s.empty()) {
printf("%d\n", s.top());
s.pop();
}
return 0;
}