二分求LIS
阿新 • • 發佈:2022-04-11
題目由leetcode1713延伸,求最長上升子序列,資料量較大時選中二分優化很快
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; #define inf 0x3f3f3f3f // int dp[200220], list[200220], a[200220]; // dp[i]儲存lis為i時最小的元素,list儲存每個元素的lis; int dp[10], list[10], a[10]; // dp[i]儲存lis為i時最小的元素,list[i]:儲存以a[i]元素結尾的lis長度; int main() { int n, i, j, k, p; while (cin >> n) { int p = 0; memset(dp, inf, sizeof(dp)); for (i = 0; i < n; i++) { scanf("%d", &a[i]); *lower_bound(dp, dp + n, a[i]) = a[i]; // 記錄更新長度對應的最大潛力元素時,順便記錄下該元素對應的LIS長度 list[p++] = lower_bound(dp, dp + n, a[i]) - dp + 1; } k = lower_bound(dp, dp + n, inf) - dp; // k:總的LIS長度 cout << k << endl; int m = k; for (i = n - 1; i >= 0; i--) { // 從右至左掃描一遍直至找全LIS長度 if (k == list[i]) dp[k--] = a[i]; if (!k) break; } for (i = 1; i <= m; i++) printf("%d\n", dp[i]); } return 0; }