zoukankan      html  css  js  c++  java
  • 题解 BZOJ 3156 防御准备

    题目大意:

    给定一个 (n)((1 <= n <= 10^6)) 以及一个长度为 (n)正整数 数列 (a) ,其中 (1 <= a_i <= 10^9)

    假设现在你在 (i) 点,你只有两个选择 :

    • 在当前点花费 (a_i) 点费用修建一个 "保卫塔"。
    • 花费 (dis) 点费用修建一个 "木偶" , (dis) 表示的就是 (i) 点右侧的第一个修建了 "保卫塔"的点到 (i) 的距离。

    特别的是,对于第 (n) 个点必须要选择修建 "保卫塔"。现在问你最小的费用是多少。

    (example:)
    (input:)

    10
    2 3 1 5 4 5 6 3 1 2
    

    (output:)

    18
    

    解题思路:

    状态设置:

    (dp[i]) 表示处理完 (1 ~ i) 的所有点的最小花费并且 (i) 必须放置 "守卫塔"。
    最后的答案自然是 (dp[n])

    状态转移:

    $dp[i] $ = (min(dp[j] + (j - i + 1) * (j - i) / 2 + A[i]) (1 <= j < i))

    随便搞一搞弄个斜率优化。

    处理 (i) 点的时候,我们假设 (j) < (k) ,并且选择 (j) 进行转移更优:
    (dp[j][1] + (j - i + 1) * (j - i) / 2 + A[i] < dp[k][1] + (k - i + 1) * (k - i) / 2 + A[i])

    (dp[j][1] - dp[k][1] < (k - i)^2 + (j - i)^2 + k - j)

    (frac{2 * (dp[j][1] - dp[k][1]) - k * (k + 1) + j * (j + 1)}{2 * (j - k)} < i)

    则这时候选择 (j) 进行转移更优秀,斜率优化即可。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    inline int read() {
        int x = 0 , flag = 1;
        char ch = getchar();
        for( ; ch > '9' || ch < '0' ; ch = getchar()) if(ch == '-') flag = -1;
        for( ; ch >= '0' && ch <= '9' ; ch = getchar()) x = (x << 3) + (x << 1) + ch - '0';
        return x * flag;
    }
    typedef double ld;
    const int MAXN = 1e6 + 50;
    int n,A[MAXN],q[MAXN];
    int dp[MAXN];
    double calc(int j,int k) {
        return (ld)(dp[j] - dp[k] + (j * (j + 1) - k * (k + 1)) / 2) / (ld)(j - k);
    }
    
    signed main() {
        n = read();
        for(int i = 1 ; i <= n ; i ++) A[i] = read();
        int l = 1 , r = 1; q[1] = 0;
        for(int i = 1 ; i <= n ; i ++) {
            while(l < r && calc(q[l], q[l + 1]) < (ld)i) l ++;
            dp[i] = dp[q[l]] + (i - q[l] - 1) * (i - q[l]) / 2 + A[i];
            while(l <= r && calc(q[r - 1], q[r]) >= calc(q[r], i)) r --;
            q[++r] = i;
        }
        cout << dp[n];
        return 0;
    }
    
    By MYCui
  • 相关阅读:
    ES6 函数——箭头函数
    ES6 变量var、let和const
    vue项目可视化管理之(vue ui)
    记录一次并发测试的bug
    python接口自动化读取json、yaml、ini文件
    python接口自动化学习笔记(封装方法用于读取excel)
    python 数据驱动(ddt,unpack)
    Python 做Django 项目遇到问题:Not Found: /c_hello(或/c_webskt/)
    下载安装破解PyCharm(转载)
    Selenium 八种元素定位方法
  • 原文地址:https://www.cnblogs.com/MYCui/p/14420563.html
Copyright © 2011-2022 走看看