[CF977F] Consecutive Subsequence

[CF977F] Consecutive Subsequence - 离散化,dp

Description

给定一个长度为n的整数数组。 你必须选择最大长度的某个子序列,使得这个子序列就形成了一个递增的连续整数序列。

Solution

先离散化(为了保持连续条件,对 (x)(x-1,x+1) 也一把丢进去)

(f[i][j]) 表示在前 (i) 个位置中,以 (j) 结尾的满足条件序列的最大长度

为了维护每个位置的转移来源点,用一个桶记录每个值最后发生更新的位置```

#include <bits/stdc++.h>
using namespace std;

#define int long long

int n;
const int N = 1e6 + 5;

int a[N], f[N], p[N], from[N];

signed main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    map<int, int> mp;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n; i++)
        mp[a[i]]++, mp[a[i] - 1]++, mp[a[i] + 1]++;
    int ind = 0;
    for (auto &[x, y] : mp)
        y = ++ind;
    for (int i = 1; i <= n; i++)
        a[i] = mp[a[i]];
    for (int i = 1; i <= n; i++)
        if (f[a[i] - 1] + 1 > f[a[i]])
        {
            f[a[i]] = f[a[i] - 1] + 1;
            from[i] = p[a[i] - 1];
            p[a[i]] = i;
        }

    cout << *max_element(f + 1, f + ind + 1) << endl;
    int pos = p[max_element(f + 1, f + ind + 1) - f];
    vector<int> ans;
    while (pos)
    {
        ans.push_back(pos);
        pos = from[pos];
    }
    while (ans.size())
    {
        cout << ans.back() << " ";
        ans.pop_back();
    }
}
原文地址:https://www.cnblogs.com/mollnn/p/14658266.html