• Codeforces Round #669 (Div. 2) D. Discrete Centrifugal Jumps


    D. Discrete Centrifugal Jumpsbu6

    题意:

    给你1到n的高楼, 现在你在1的位置你可每次从 i 到 i + 1, 或者跳到 i < j 且 (max(h[i], h[j]) < min(h[i + 1] ...,h[j - 1]))

    或者跳 i < j 且 (min(h[i], h[j]) > max(h[i + 1], ......, h[j - 1]))

    问最少需要跳多少下可以从1到n

    题解:

    这题不难想到dp

    比赛的时候贪心, 每个位置能跳的最远位置, 然后dp, 后来被hack了

    比如这个样例

    8
    20 3 4 19 20 21 20 19
    如果贪心每个位置跳的最远位置,那么第一个可以跳到5然后第五个在跳到第7个, 第7个跳到第8个, 总共跳了3次
    但是 答案是2次, 第一个位置可以跳到 第四个位置, 然后第四个位置跳到最后一个位置。
    

    如果这题可以暴力那么就直接把每个位置能走的点都走了, 然后选一个最小的。

    时间肯定不行。

    如果加上记忆化暴力了, 那就是 o((n ^ 2)) 也就是(n ^ 2)的dp

    n是3e5 还不行。

    如果加上 单调栈维护dp就可以把复杂度降到 o(n)了

    用两个单调栈, q, q1, q维护严格单调递减, 当出栈是表示 q.top()的元素可以得到i

    也就是 把i所有能去的地方都枚举到了

    同理q1维护 严格单调递增

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 3e5 + 7;
    
    int n, a[N], dp[N];
    
    stack<int> q, q1;
    
    int main() {
        ios::sync_with_stdio(0);
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            dp[i] = n + 1;
        }
        dp[1] = 0;
        for (int i = 1; i <= n; i++) {
            dp[i] = min(dp[i - 1] + 1, dp[i]);
            while (!q.empty() && a[q.top()] <= a[i]) {
                int x = a[q.top()];
                q.pop();
                if (a[i] == x) continue;
                if (!q.empty()) {
                    dp[i] = min(dp[i], dp[q.top()] + 1);
                }
            }
    
            while (!q1.empty() && a[q1.top()] >= a[i]) {
                int x = a[q1.top()];
                q1.pop();
                if (x == a[i]) continue;
                if (!q1.empty()) {
                    dp[i] = min(dp[i], dp[q1.top()] + 1);
                }
            }
            q.push(i);
            q1.push(i);
            
        }
        cout << dp[n]  << endl;
    
    
    }
    
  • 相关阅读:
    mysql 一
    scanf函数的返回值问题
    统计一个数分解质因数中不同因子的个数
    统计一个数分解质因数中不同因子的个数
    统计一个数分解质因数中不同因子的个数
    GridControl控件和TreeList控件设置标志图
    GridControl控件和TreeList控件设置标志图
    GridControl控件和TreeList控件设置标志图
    btn按钮之间事件相互调用
    btn按钮之间事件相互调用
  • 原文地址:https://www.cnblogs.com/BOZHAO/p/13638130.html
Copyright © 2020-2023  润新知