zoukankan      html  css  js  c++  java
  • Codeforces Round #669 (Div. 2) D

    题解

    想想应该明白, (i < j < k) i -> j ->k, 必然能够直接 i -> k

    那就是线性dp了, 从 1 一直到 n 点, dp就完事, 关键是如何转移,

    或者说是 i 能到达哪些点?

    想想应该明白, (i < j < k) i -> j ->k, 必然能够直接 i -> k

    所以我们只需要求得

    正解单调栈预处理, 没啥意思, 看了rk1的代码, 有点意思

    很巧妙的处理方式,

    和前几天写的, 拿到前缀和处理一样巧妙, 用后续节点去更新前面的节点

    至于 max h[i + 1 ~ j - 1] < min(h[i], h[j]) 和 min h[i+ 1 ~ j - 1] > max(h[i], h[j]) 本质一样的

    你把 h[i] = -h[i], 不就把 max 变成 min了, 说白了相同算法, h取负数算两次就行, 那我们直接考虑 max

    只要按从到大小顺序取, 那么 对于 a < b 只要不存在 c(a < c < b) 比 a, b 先取出来(h[c] > min(h[a], h[b])) a -> b 就可以连接

    如果存在这个c, 且不存在 d(a < d < c) 比 a, c 先取出来(h[d] > min(h[a], h[c])) a -> c就可以连接 ...(无限套娃)

    按从大到小取出 b 时, 我们能直接得到 a (已经被取出, 且所有取出的数, a,b 距离最近) 就可以链接 a -> b,

    用 set 维护 取出的集合就好了!

    同时我们还要考虑 b(刚被取出) -> c(c已经被取出), 我们要确保没有 d(未被取出, h[d] == h[b], d < c), 就可以 b -> c

    剩下的 dp就好了

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define per(i,a,b) for(int i=(a);i>=(b);--i)
    #define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    typedef vector<int> VI;
    typedef double db;
    
    const int N = 1e4 + 5;
    
    int n, m, _, k, x, y;
    
    int main() {
        IOS;
        cin >> n; VI a(n), b(n);
        vector<VI> e(n);
        for (auto& i : a) cin >> i;
        rep(i, 0, n - 1) b[i] = i;
        rep(cas, 1, 2) {
            for (auto& i : a) i = -i;
            sort(all(b), [&](int& x, int& y) {
                return tie(a[x], x) < tie(a[y], y);
            });
            set<int> st;
            rep(i, 0, n - 1) {
                st.insert(b[i]);
                auto cur = st.find(b[i]), ne = next(cur);
                if (cur != st.begin()) e[*prev(cur)].pb(b[i]);
                if (ne != st.end() && (i + 1 == n ||
                    a[b[i + 1]] != a[b[i]] || b[i + 1] > * ne)) e[b[i]].pb(*ne);
            }
        }
        VI f(n, 1e8); f[0] = 0;
        rep(i, 0, n - 1)
            for (auto& j : e[i]) f[j] = min(f[j], f[i] + 1);
        cout << f[n - 1] << '
    ';
        return 0;
    }
    
  • 相关阅读:
    Just Do It:战胜拖延症(终极大法!)
    拖延是一种什么病
    数学之美系列二十三 谈谈香农第一定律
    深度挖掘
    当机器统治世界
    算法是如何秘密左右我们的行为方式
    比人类更强:为什么机器人终将也必将接手我们的工作?
    Google移动的未来在哪里?Google Now
    数学之美系列十九 马尔可夫链的扩展 贝叶斯网络 (Bayesian Networks)
    Matlab与COM应用(一)——COM技术概述
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13638578.html
Copyright © 2011-2022 走看看