• luogu 1714 切蛋糕


    题目

    题目描述

    今天是小Z的生日,同学们为他带来了一块蛋糕。这块蛋糕是一个长方体,被用不同色彩分成了N个相同的小块,每小块都有对应的幸运值。

    小Z作为寿星,自然希望吃到的第一块蛋糕的幸运值总和最大,但小Z最多又只能吃M小块(M≤N)的蛋糕。

    吃东西自然就不想思考了,于是小Z把这个任务扔给了学OI的你,请你帮他从这N小块中找出连续的k块蛋糕(k≤M),使得其上的幸运值最大。

    输入格式

    输入文件cake.in的第一行是两个整数N,M。分别代表共有N小块蛋糕,小Z最多只能吃M小块。

    第二行用空格隔开的N个整数,第i个整数Pi代表第i小块蛋糕的幸运值。

    输出格式

    输出文件cake.out只有一行,一个整数,为小Z能够得到的最大幸运值。

    输入输出样例

    输入 #1
    5 2
    1 2 3 4 5
    输出 #1
    9
    输入 #2
    6 3
    1 -2 3 -4 5 -6
    输出 #2
    5

    说明/提示

    对20%的数据,N≤100。

    对100%的数据,N≤500000,|Pi|≤500。 答案保证在2^31-1之内。

    分析

    emmmmm,第一反应是动规,后来发现好像不太好实现

    他对子段长进行了限制,跟单调队列的区间长限制何其相似

    关于区间和,除了线段树等数据结构,还有前缀和,

    加上前缀和,这道题就变成了相距不超过M的两个数的最大差

    我们可以用单调队列求解

    单调队列中单调递增(求最大差)

    代码

     1 /**************************
     2 User:Mandy.H.Y
     3 Language:c++
     4 Problem:luogu1440
     5 Algorithm:
     6 **************************/
     7 #include<bits/stdc++.h>
     8 
     9 using namespace std;
    10 
    11 const int maxn = 5e5 + 5;
    12 
    13 int n,l,r,m;
    14 long long ans = -1e15;
    15 int q[maxn],a[maxn];
    16 
    17 template<class T>inline void read(T &x){
    18     x = 0;bool flag = 0;char ch = getchar();
    19     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
    20     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
    21     if(flag) x = -x;
    22 }
    23 
    24 template<class T>void putch(const T x){
    25     if(x > 9) putch(x / 10);
    26     putchar(x % 10 | 48);
    27 }
    28 
    29 template<class T>void put(const T x){
    30     if(x < 0) putchar('-'),putch(-x);
    31     else putch(x);
    32 }
    33 
    34 void file(){
    35     freopen("1440.in","r",stdin);
    36     freopen("1440.out","w",stdout);
    37 }
    38 
    39 void readdata(){
    40     read(n);read(m);
    41 }
    42 
    43 void work(){
    44     //前缀和 
    45     for(int i = 1; i <= n ; ++ i){
    46         read(a[i]);a[i] += a[i - 1];
    47         while(l < r && i - q[l] > m) l++;
    48         //这里 i - q[l] > m,因为a[i] - a[j-1]才是j到i的区间和 
    49 //        ans = max(ans,(long long)a[i]);不能要,a[i]是前缀和 
    50         ans = max(ans,(long long)a[i] - a[q[l]]);
    51         while(l < r && a[q[r-1]] >= a[i]) r--;//>=
    52         q[r++]  = i;
    53     }
    54     put(ans);
    55 }
    56 
    57 int main(){
    58 //    file();
    59     readdata();
    60     work();
    61     return 0;
    62 }
    View Code
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    linux 安装jdk
    linux 安装 Redis
    jvisualvm监控远程jvm的两种连接方式
    list转map(JDK8-Lambda表达式)
    循环删除list中的某一元素的三种方式
    SpringBoot-@ControllerAdvice 拦截异常并统一处理
    Spring-@ControllerAdvice 拦截异常并统一处理
    Tomcat系列
    thinkPHP5.1模型User设计
    uniapp后台api设计(微信user表)
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11417178.html
Copyright © 2020-2023  润新知