Unverified Commit 64923531 authored by zhangmin chen's avatar zhangmin chen Committed by GitHub
Browse files

Update monotonous-queue-stack.md

添加单调队列的参考代码
parent 940f096c
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -29,6 +29,66 @@ author: TrisolarisHD, hsfzLZH1, Ir1d, greyqz, Anguei, billchenchina, Chrogeek, C

总的时间复杂度为 $O(nm)$ 。

???+ 参考代码
    ```bash
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    const int maxn = 150000 + 10;
    const int maxm = 300 + 10;
    const ll inf = 0xcfcfcfcfcfcfcfcf;

    ll f[2][maxn];
    ll a[maxm], b[maxm], t[maxm];
    int n, m, d;

    int que[maxn];
    int fl = 1;
    
    void init() {
        memset(f, inf, sizeof(f));
        memset(que, 0, sizeof(que));
        _rep(i, 1, n) f[0][i] = 0;
        fl = 1;
    }



    void dp() {
        init();
        for(int i = 1; i <= m; i++) {
            int l = 1, r = 0;

            int k = 1;
            for(int j = 1; j <= n; j++) {
                for (; k <= min(1ll*n, j+d*(t[i]-t[i-1])); k++) {
                    while (l <= r && f[fl^1][que[r]] <= f[fl^1][k]) r--;
                    que[++r] = k;
                }

                while (l <= r && que[l] < max(1ll, j-d*(t[i]-t[i-1])) ) l++;
                f[fl][j] = f[fl^1][que[l]] - abs(a[i]-j) + b[i];
            }

            fl ^= 1;
        }
    }

    int main() {
        cin >> n >> m >> d;
        _rep(i, 1, m) {
            cin >> a[i] >> b[i] >> t[i];
        }

        dp();
        ll ans = inf;
        _rep(i, 1, n) ans = max(ans, f[fl^1][i]);
        cout << ans << endl;
    }
    ```

讲完了,让我们归纳一下单调队列优化动态规划问题的基本形态:当前状态的所有值可以从上一个状态的某个连续的段的值得到,要对这个连续的段进行 RMQ 操作,相邻状态的段的左右区间满足非降的关系。

## 单调队列优化多重背包