原題:
https://cses.fi/problemset/task/1145
題意:
給長度 n 的序列,求「嚴格遞增」子序列的最長長度。(只需輸出長度)
解題思路:
O(N log N) tails(lower_bound)。
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n;
    cin >> n;
    vector<long long> a(n);
    for (int i = 0; i<n; i++) cin >> a[i];
    vector<long long> tails; // tails[len-1] = 長度 len 的最小結尾
    tails.reserve(n);
    for (int i = 0; i<n; i++) {
        long long x = a[i];
        // 嚴格遞增 → 找第一個 >= x 的位置
        auto it = lower_bound(tails.begin(), tails.end(), x);
        if (it == tails.end()) tails.push_back(x);
        else *it = x;
    }
    cout << (int)tails.size() << "\n";
    return 0;
}
原題:
https://leetcode.com/problems/longest-increasing-subsequence/description/
題意:
回傳 LIS 長度(嚴格遞增)。
解題思路:
提供兩版:O(N log N) 與 O(N²)。
解法1:O(N log N)(tails)
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> tails;
        tails.reserve(nums.size());
        for (int i = 0; i<nums.size(); i++) {
            int x = nums[i];
            // 嚴格遞增 → lower_bound
            auto it = lower_bound(tails.begin(), tails.end(), x);
            if (it == tails.end()) tails.push_back(x);
            else *it = x;
        }
        return tails.size();
    }
};
解法2:O(N²)(經典 DP)
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        if (n == 0) return 0;
        vector<int> dp(n+1, 1);
        int best = 1;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]) {
                    if (dp[j] + 1 > dp[i]) dp[i] = dp[j] + 1;
                }
            }
            if (dp[i] > best) best = dp[i];
        }
        return best;
    }
};