zoukankan      html  css  js  c++  java
  • [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();
        }
    }
    
  • 相关阅读:
    关于++i和i++的左值、右值问题
    运算符优先级
    计算机中的数及其编码
    递归函数
    PHP读取excel(4)
    替换元素节点replaceChild()
    子结点childNodes
    插入节点insertBefore()
    创建节点createElement
    插入节点appendChild()
  • 原文地址:https://www.cnblogs.com/mollnn/p/14658266.html
Copyright © 2011-2022 走看看