题解 | #最长上升子序列(一)#

最长上升子序列(一)

http://www.nowcoder.com/practice/5f65ccbb025240bd8458eb6479c2612e

常规动态规划

#include <iostream>
#include <vector>

using namespace std;

class solution
{
public:
    int getResult(vector<int> &nums)
    {
        int n = nums.size();
        vector<int> dp(n, 1);
        int ret = dp[0];
        
        for (int i = 1; i < n; i++)
        {
            for (int j = 0; j < i; j++)
            {
                if (nums[i] > nums[j])
                {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
            ret = max(ret, dp[i]);
        }
        
        return ret;
    }
};

int main()
{
    int n;
    solution mSolution;
    
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i < n; i++)
    {
        cin >> nums[i];
    }
    cin.get();
    cout << mSolution.getResult(nums) << endl;
    
    return 0;
}

二分+贪心

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class solution
{
public:
        int getResult(vector<int> &nums)
    {
        int n = nums.size();
        vector<int> dp(n);
        dp[0] = nums[0];
        int len = 1;
        
        for (int i = 1; i < n; i++)
        {
            if (nums[i] > dp[len - 1])
            {
                dp[len++] = nums[i];
            }
            else
            {
                int j = lower_bound(dp.begin(), dp.begin() + len, nums[i]) - dp.begin();
                dp[j] = nums[i];
            }
        }
        
        return len;
    }
};

int main()
{
    int n;
    solution mSolution;
    
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i < n; i++)
    {
        cin >> nums[i];
    }
    cin.get();
    cout << mSolution.getResult(nums) << endl;
    
    return 0;
}

树状数组

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>

using namespace std;

struct Node
{
    int __val;
    int __idx;
    Node(int val, int idx) : __val(val), __idx(idx) {}
};

class TreeVec
{
public:
    TreeVec(int n)
    {
        __tVec = vector<int>(n, 0);
    }
    
    int lowerbit(int x)
    {
        return x & (-x); // x & (~x + 1)
    }
    
    void modify(int x, int y)
    {
        while (x < __tVec.size())
        {
            __tVec[x] = max(__tVec[x], y);
            x += lowerbit(x);
        }
    }
    
    int query(int x)
    {
        int ret = INT_MIN;
        while (x)
        {
            ret = max(ret, __tVec[x]);
            x -= lowerbit(x);
        }
        
        return ret;
    }

public:
    vector<Node> __nodeVec;
    vector<int> __tVec;
};

class solution
{
public:
    int getResult(vector<int> &nums, int n)
    {
        TreeVec mTreeVec(nums.size());
        
        for (int i = 1; i < n; i++)
        {
            mTreeVec.__nodeVec.emplace_back(Node(nums[i], i));
        }
        sort(mTreeVec.__nodeVec.begin(), mTreeVec.__nodeVec.end(), [](Node a, Node b)
             {
                 return a.__val == b.__val ? a.__idx < b.__idx : a.__val < b.__val;
             });
        
        int ret = INT_MIN;
        for (auto [val, idx] : mTreeVec.__nodeVec)
        {
            int tMax = mTreeVec.query(idx);
            mTreeVec.modify(idx, ++tMax);
            ret = max(ret, tMax);
        }
        
        return ret;
    }
};

int main()
{
    int n;
    solution mSolution;
    
    cin >> n;
    vector<int> nums(n + 1); // 树状数组下标从1开始
    for (int i = 1; i <= n; i++)
    {
        cin >> nums[i];
    }
    cin.get();
    
    int m = unique(nums.begin(), nums.end()) - nums.begin(); // 去重操作,不去重就是最长非下降子序列
    
    cout << mSolution.getResult(nums, m) << endl;
    
    return 0;
}
全部评论

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务