簡體   English   中英

最長遞增子序列與追蹤

[英]Longest increasing subsequence and tracing

給你一個整數序列,找到給定數字序列的最長和最大的字典順序子序列

|a[i]| <= 2.10^9

output:

— 打印最長子序列的長度

  • 打印最大的字典順序子序列

錄像機

輸入

6

1 2 4 3 5 6

output

5

1 2 4 5 6

這是我的代碼,但它是錯誤的

#include <bits/stdc++.h>
#define ll long long
#define maxn int(3e6) + 5
#define ii pair<ll, ll>
#define iii pair<ll, ii>
#define F first
#define S second
#define oo 1e16
#define sz(x) x.size() * 1ll
#define all(x) x.begin(), x.end()
#define mem(x, k) memset(x, k, sizeof x)
#define tb {clock_t start, en; double time_use; start = clock();}
#define te {en = clock(); cout << '\n'; time_use = (double)(en - start) / CLOCKS_PER_SEC; cout<<"Thoi gian chay : "<<time_use << '\n';}
using namespace std;
ll n;
ll a[maxn];
ll num[maxn];
ll trace[maxn];

struct BIT{
    vector<ll> bit;
    BIT(int n){
        bit.resize(n + 4, 0);
    }

    int gbit(int x){
        return x & (- x);
    }

    void update(int x, ll val, int n){
        for(;x <= n; x += gbit(x))
            bit[x] = max(bit[x], val);
    }

    ll getbit(ll y, ll &tmp){
        ll ans = 0;
        for(; y > 0; y -= gbit(y)){
            if(bit[y] > ans){
                ans = bit[y];
                tmp = 0;
            }
            if(ans == bit[y]){
                tmp = max(tmp, y);
            }
        }
        return ans;
    }

};

int main() {
//    ifstream cin("test.inp");
//    ofstream cout("test.out");
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    {// number compression
        vector<ll> s;
        for(int i = 1; i <= n; i ++){
            cin >> a[i];
            a[i] += 2e9;
            s.push_back(a[i]);
        }
        sort(all(s));
        vector<ll> b;
        b.push_back(s[0]);
        for(int i = 1; i < sz(s); i ++)
            if(s[i] != s[i - 1]) b.push_back(s[i]);

        for(int i = 1; i <= n; i ++){
            int x = a[i];
            a[i] = lower_bound(all(b), a[i]) - b.begin() + 1;
            num[a[i]] = x;
        }
    }

    BIT b(maxn - 5);
    ll tmp = 0;
    ll ans = 0, en = 0;
    for(int i = 1; i <= n; i ++){
        tmp = 0;
        int p = b.getbit(a[i] - 1, tmp);
        if(p + 1 > ans){
            ans = p + 1;
            en = a[i];
        }
        b.update(a[i], p + 1, maxn - 5);
        trace[a[i]] = tmp;
        //printf("%lld %lld\n", a[i], tmp);
    }
    cout << ans << '\n';
    vector<ll> tp;
    while(en > 0){
        tp.push_back(en);
        en = trace[en];
    }
    reverse(all(tp));
    for(int x: tp)
        cout << num[x] - 2e9 << '\n';

}

我用BIT解決但是trace是錯誤的

我想不出解決方案,請幫助我!

實際的 C++ 代碼看起來更像這樣,讓您了解我在說什么(未完全測試):

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

// helper struct to make code more readable. 
struct sub_range
{
    std::size_t length()
    {
        return end - begin;
    }

    std::size_t begin{ 0ul };
    std::size_t end{ 1ul};      // inclusive end, unlike iterators which have end one beyond end.
};

std::vector<std::int64_t> GetLongestSubRange(const std::vector<std::int64_t>& values)
{
    sub_range longest_range;
    sub_range current_range;

    // always test your input. 
    if (values.size() < 1) return values;

    for (std::size_t prev_pos{ 0ul }, pos{ 1ul }; pos < values.size(); ++pos, ++prev_pos)
    {
        // still ordered so extend length of current range
        if (values[prev_pos] <= values[pos])
        {
            current_range.end = pos;
        }
        else
        {
            // if current range is longer then previous longest range
            // then updated longest_range
            if (current_range.length() > longest_range.length())
            {
                longest_range = current_range;
            }

            // and start detecting a new range at current position
            current_range.begin = pos;
            current_range.end = pos;
        }
    }

    // return a sub vector, the +1ul is because subrange is inclusive range and STL works with exclusive end.
    return std::vector<std::int64_t>{ values.begin() + longest_range.begin, values.begin() + longest_range.end + 1ul};
};


int main()
{
    auto subrange = GetLongestSubRange({ 1, 2, 4, 3, 5, 6, 7, 8, 9, 2 });

    // output the longest subrange
    for (const auto& v : subrange) std::cout << v << " ";

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM