zoukankan      html  css  js  c++  java
  • [Vijos1617] 超级教主(DP + 单调队列)

    传送门

    设 f[i] 表示吃完 f[i] 及其以下的能量球后所剩下的能

    所以 f[i] = max(f[i], f[j] + (sum[i] - sum[j]) - i * 100) ( 0 <= j < i )

    但这是 O(n2) 的,肯定超时,

    把上面的式子变换以下得到 f[i] = max(f[i], (f[j] - sum[j]) + sum[i] - i * 100) ( 0 <= j < i )

    也就是说,f[i] 只与 f[j] - sum[j] 有关,sum[i] - i * 100 可看做常数,

    要想使 f[i] 最大,需要让 f[j] - sum[j] 最大,

    可用单调队列维护最大 f[j] - sum[j],

    如果 f[q[h]] < i * 100 说明能量不够跳到当前点,而能量跳不到当前点肯定也跳不到后面的点,h++

    ——代码

     1 #include <cstdio>
     2 
     3 const int MAXN = 2000001;
     4 int n, m, h = 1, t;
     5 int sum[MAXN], q[MAXN], f[MAXN];
     6 
     7 int main()
     8 {
     9     int i, j, x;
    10     scanf("%d %d", &n, &f[0]);
    11     for(i = 1; i <= n; i++)
    12     {
    13         scanf("%d", &x);
    14         sum[i] = x + sum[i - 1];
    15     }
    16     t++;
    17     for(i = 1; i <= n; i++)
    18     {
    19         while(h <= t && f[q[h]] < i * 100) h++;
    20         f[i] = f[q[h]] - sum[q[h]] + sum[i] - i * 100;
    21         while(h <= t && f[q[t]] - sum[q[t]] < f[i] - sum[i]) t--;
    22         q[++t] = i;
    23     }
    24     printf("%d", f[n]);
    25     return 0;
    26 }
    View Code
  • 相关阅读:
    在 Spring 中使用 Quartz
    Quartz 快速进阶
    任务调度概述
    Spring Boot 2.x 整合 Mybatis 3.x
    pwd函数实现
    07-图4 哈利·波特的考试 (25 分)
    06-图3 六度空间 (30 分)
    linux中的目录
    Linux中的文件
    06-图2 Saving James Bond
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6821200.html
Copyright © 2011-2022 走看看