[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();
}
}