zoukankan      html  css  js  c++  java
  • #区间dp,离散#D 弱者对决

    题目


    分析

    (dp[i][j][x])表示当前区间为([i,j]),最小值为(x)的最大总分,
    状态转移方程可以用后缀最大值优化到(O(n^3m)),主要难点是输出方案
    后缀最大值需要记录是在哪个位置取得最大值


    代码

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int N = 4011, M = 61;
    int n, m, tot, c[N], a[N], b[N], L[N], R[N];
    int dp[M][M][N], f[M][M][N], p[M][M][N], pf[M][M][N];
    inline signed iut() {
        rr int ans = 0;
        rr char c = getchar();
        while (!isdigit(c)) c = getchar();
        while (isdigit(c)) ans = (ans << 3) + (ans << 1) + (c ^ 48), c = getchar();
        return ans;
    }
    inline void print(int ans) {
        if (ans > 9)
            print(ans / 10);
        putchar(ans % 10 + 48);
    }
    inline void calc(int l, int mid, int r) {
        for (rr int i = 1; i <= tot; ++i) c[i] = 0;
        for (rr int i = 1; i <= m; ++i)
            if (l <= L[i] && L[i] <= mid && mid <= R[i] && R[i] <= r)
                ++c[a[i]];
    }
    inline void dfs(int l, int r, int now) {
        rr int mid = p[l][r][now];
        if (l < mid)
            dfs(l, mid - 1, pf[l][mid - 1][now]);
        printf("%d ", b[now]);
        if (mid < r)
            dfs(mid + 1, r, pf[mid + 1][r][now]);
    }
    signed main() {
        freopen("baddream.in", "r", stdin);
        freopen("baddream.out", "w", stdout);
        n = iut(), m = iut();
        for (rr int i = 1; i <= m; ++i) L[i] = iut(), R[i] = iut(), b[i] = a[i] = iut();
        sort(b + 1, b + 1 + m), tot = unique(b + 1, b + 1 + m) - b - 1;
        for (rr int i = 1; i <= m; ++i) a[i] = lower_bound(b + 1, b + 1 + tot, a[i]) - b;
        for (rr int i = n; i >= 1; --i)
            for (rr int j = i; j <= n; ++j) {
                for (rr int k = i; k <= j; ++k) {
                    calc(i, k, j);
                    for (rr int o = tot, sum = 0; o; --o) {
                        sum += c[o];
                        rr int now = dp[i][k - 1][o] + dp[k + 1][j][o] + sum * b[o];
                        if (now >= f[i][j][o])
                            f[i][j][o] = now, p[i][j][o] = k;
                    }
                }
                for (rr int o = tot; o; --o)
                    if (f[i][j][o] >= dp[i][j][o + 1])
                        dp[i][j][o] = f[i][j][o], pf[i][j][o] = o;
                    else
                        dp[i][j][o] = dp[i][j][o + 1], pf[i][j][o] = pf[i][j][o + 1];
            }
        printf("%d
    ", dp[1][n][1]);
        dfs(1, n, pf[1][n][1]);
        return 0;
    }
    
  • 相关阅读:
    emacs jedi
    opencv 基本demo
    emacs列编辑
    observable operator example
    angular keydown 例子
    回调和匿名函数
    gin cors
    angular rxjs
    python dbus note
    视频截图
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14074913.html
Copyright © 2011-2022 走看看