zoukankan      html  css  js  c++  java
  • 洛谷P1714 切蛋糕(双端队列)

    题目地址:https://www.luogu.com.cn/problem/P1714

    题意:给定n个数,从中选择最多m个连续的数,使得这些数的和最大

    输入:第一行n,m。第二行,n个整数

    输出:输出所选择的数的和

    题解:这道题第一感觉肯定是前缀和,但是这里有一个难点,就是最多是选择m个连续的数,而不是一定是m个数,所以这里面的复杂度就会有点高(如果暴力的话)。暴力就是找到第i个数的前面m个前缀和的最小值,二者相减,然后去所有i的这二种结果的最大值,这里如果暴力找到m个前缀和的最小值,复杂度会非常高。所以我们可以通过双端队列来实现单调队列的方法来求解最小值。

    AC代码:

    #include<iostream>
    #include<deque> 
    using namespace std;
    const int N=500000+5;
    int sum[N];//前缀和数组
    
    int main(){
        deque<int>de;
        int n,m;
        cin>>n>>m;
        sum[0]=0;
        for(int i=1;i<=n;i++){
            cin>>sum[i];
            sum[i]+=sum[i-1];
        } 
        int ans=0;
        for(int i=1;i<=n;i++){
            while(!de.empty()&&*de.begin()<i-m) de.pop_front();//如果队列de中的最小值已经不再i的前m个范围,那么i和i以后的数都不会用到这个最小值了,所以出队 
            while(!de.empty()&&sum[*(de.end()-1)]>=sum[i]) de.pop_back();//如果sum[i]小于等于队列的尾部元素,那么以后所有的i的前m个前缀和的最小值都不可能是此时队列的尾部元素 
            de.push_back(i);
            ans=max(ans,sum[i]-sum[*de.begin()]);
        } 
        cout<<ans;
        return 0;
    }

    写于2020/8/6 11:59


    作者:孙建钊
    出处:http://www.cnblogs.com/sunjianzhao/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    原生js中,call(),apply(),bind()三种方法的区别
    jQuery回溯!!!!!!!
    java中异常类与类别
    Java 多线程(并发)
    Java中反射与常用方法
    漫谈计算机构成
    java语言特性(相比C++)
    初级排序算法学习笔记
    java中参数传递
    关于类的知识
  • 原文地址:https://www.cnblogs.com/sunjianzhao/p/13445448.html
Copyright © 2011-2022 走看看