• hdu3507(初识斜率优化DP)


    hdu3507

    题意

    给出 N 个数字,输出的时候可以选择连续的输出,每连续输出一串,它的费用是 这串数字和的平方加上一个常数 M。

    分析

    斜率优化dp,入门题。

    参考
    参考

    得到 dp 方程后,发现是O(n * n)的复杂度,且 n 很大,考虑用斜率优化。

    设 s[i] 为 1 到 i 的花费之和。
    dp方程:(dp[i] = dp[j] + (s[i] - s[j])^2 + m ( i > j))
    如果选 j 比选 k 更优,则有 (dp[j] + (s[i] - s[j])^2 + m < dp[k] + (s[i] - s[k])^2 + m)
    移项可得, $(dp[j] + s[j]^2 - (dp[k] + s[k]^2)) / (2 * (s[j] - s[k])) < s[i] $
    这样形成类似于求斜率的式子。
    那么满足这个式子,是由于前提条件:j 比 k 更优,即选 j 花费更少。

    令 $ g[j, l] = (dp[l] + s[l]^2 - (dp[j] + s[j]^2)) / (2 * (s[l] - s[j]))$

    code

    #include<cstdio>
    using namespace std;
    const int MAXN = 5e5 + 5;
    int s[MAXN], q[MAXN], dp[MAXN];
    int n, m;
    int up(int k, int j) {
        return dp[j] + s[j] * s[j] - (dp[k] + s[k] * s[k]);
    }
    int down(int k, int j) {
        return 2 * (s[j] - s[k]);
    }
    int get(int i, int j) {
        return dp[j] + (s[i] - s[j]) * (s[i] - s[j]) + m;
    }
    int main() {
        while(~scanf("%d%d", &n, &m)) {
            s[0] = 0;
            dp[0] = 0;
            for(int i = 1; i <= n; i++) {
                scanf("%d", &s[i]);
                s[i] += s[i - 1];
            }
            int head = 0, tail = 0;
            q[tail++] = 0;
            for(int i = 1; i <= n; i++) {
                while(head + 1 < tail && up(q[head], q[head + 1]) <= s[i] * down(q[head], q[head + 1]))
                    head++;
                dp[i] = get(i, q[head]);
                // g[k,j] >= g[j,l] (k < j < l) 说明 j 可以舍去
                while(head + 1 < tail && up(q[tail - 2], q[tail - 1]) * down(q[tail - 1], i) >= up(q[tail - 1], i) * down(q[tail - 2], q[tail - 1]))
                    tail--;
                q[tail++] = i;
            }
            printf("%d
    ", dp[n]);
        }
        return 0;
    }
    
  • 相关阅读:
    轮播图案例
    如何使用google等一系列搜索引擎?
    开源项目weiciyuan运行前gradle调试过程记录
    onRetainNonConfigurationInstance方法状态保存
    关于stickybroadcast
    关于Bundle对象的思考
    android中finish和system.exit方法退出的区别
    关于RAW 和 ASSEST文件夹的差异
    图片缓存核心类LruCache
    Android常用开源库集合【持续更新】
  • 原文地址:https://www.cnblogs.com/ftae/p/7001841.html
Copyright © 2020-2023  润新知