1 条题解

  • 0
    @ 2022-12-25 15:02:08

    O(n2)O(n^2)

    #include <bits/stdc++.h>
    using namespace std;
    int n;
    int a[1005];
    int dp[1005]; // dp[i]: 以 a[i] 结尾的最长上升子序列的长度
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        int ans = 0;
        for (int i = 1; i <= n; i++)
        {
            dp[i] = 1;
            // 考虑前面的位置 j
            for (int j = i - 1; j >= 1; j--)
            {
                // 如果 a[i] 可以接在 a[j] 后面构成上升子序列
                if (a[i] > a[j])
                    dp[i] = max(dp[i], dp[j] + 1);
            }
            ans = max(ans, dp[i]);
        }
        cout << ans << "\n";
        return 0;
    }
    

    O(nlogn)O(n\log n)

    #include <bits/stdc++.h>
    using namespace std;
    int n;
    int a[1005];
    int dp[1005]; // dp[i]: 以 a[i] 结尾的 LIS 的长度
    int f[1005];  // f[len]: 当前长度为 len 的 LIS 的结尾最小值
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            f[i] = 10001;
        }
        int ans = 0;
        for (int i = 1; i <= n; i++)
        {
            // 找到第一个 f[len] 大于 a[i] 的 len
            int l = 1;
            int r = n;
            int len = 1;
            while (l <= r)
            {
                int mid = (l + r) / 2;
                if (f[mid] > a[i])
                {
                    len = mid;
                    r = mid - 1;
                }
                else
                {
                    l = mid + 1;
                }
            }
            // 更新 dp、f、ans
            dp[i] = len;
            f[len] = a[i];
            ans = max(ans, dp[i]);
        }
        cout << ans << "\n";
        return 0;
    }
    
    • 1

    信息

    ID
    500
    时间
    1000ms
    内存
    128MiB
    难度
    4
    标签
    (无)
    递交数
    69
    已通过
    30
    上传者