洛谷P1714 切蛋糕 单调队列做法

news2025/11/5 4:26:54

原题链接

https://www.luogu.com.cn/problem/P1714


题面

题目描述

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

小 Z 作为寿星,自然希望吃到的蛋糕的幸运值总和最大,但小 Z 最多又只能吃 m ( m ≤ n ) m(m\le n) m(mn) 小块的蛋糕。

请你帮他从这 n n n 小块中找出连续 k ( 1 ≤ k ≤ m ) k(1 \le k\le m) k(1km) 块蛋糕,使得其上的总幸运值最大。

形式化地,在数列 { p n } \{p_n\} {pn} 中,找出一个子段 [ l , r ] ( r − l + 1 ≤ m ) [l,r](r-l+1\le m) [l,r](rl+1m),最大化 ∑ i = l r p i \sum\limits_{i=l}^rp_i i=lrpi

输入格式

第一行两个整数 n , m n,m n,m。分别代表共有 n n n 小块蛋糕,小 Z 最多只能吃 m m m 小块。

第二行 n n n 个整数,第 i i i 个整数 p i p_i pi 代表第 i i i 小块蛋糕的幸运值。

输出格式

仅一行一个整数,即小 Z 能够得到的最大幸运值。

样例 #1

样例输入 #1

5 2 1 2 3 4 5

样例输出 #1

9

样例 #2

样例输入 #2

6 3 1 -2 3 -4 5 -6

样例输出 #2

5

提示

数据规模与约定
  • 对于 20 % 20\% 20% 的数据,有 1 ≤ n ≤ 100 1\le n\le100 1n100
  • 对于 100 % 100\% 100% 的数据,有 1 ≤ n ≤ 5 × 1 0 5 1\le n\le5\times 10^5 1n5×105 ∣ p i ∣ ≤ 500 |p_i|≤500 pi500

保证答案的绝对值在 [ 0 , 2 31 − 1 ] [0,2^{31}-1] [0,2311] 之内。


解题思路

求连续区间和,我们很容易想到前缀和,我们先预处理出前缀和数组s(s[i]=s[1]+s[2]+s[3]+……s[i-1]+s[i]),
然后我们首先有个非常朴素的想法是:对于以第i个元素结尾的子段,最大的子段和P(i)可以表示为P[i] = max{sum[i] - sum[j],i - m <= j <= i - 1},
于是有ans = max[P[i]],用O(n^2)的朴素算法枚举算出每个窗口区间的和然后找最大,
即:

for (int i = 1; i <= n; i++) {
   cin >> s[i];
   s[i] = s[i - 1] + s[i];
}
// 暴力解法,求出前缀和之后,用O(n^2)的朴素算法算出每个窗口区间的和,会超时
ll ans = -INF;
for (int i = 1; i <= n; i++) {
   for (int j = i - m + 1; j <= i; j++) {
       ans = max(ans, s[i] - s[j - 1]);    // [j, i]的区间和
   }
}
cout << ans << endl;

结合题目数据,这显然会超时。
我们考虑在这个朴素解法的基础上进行优化,将上面P[i]的计算式改写为
P[i] = sum[i] - min{sum[j], i - m <= k <= i - 1},
于是我们就要想方设法在优于O(M)的时间内实现获取最小的sum[j]。这个sum[j]必须是[i - m, i - 1]区间内最小的。
考虑设计这样一个数据结构,在更低的时间复杂度内获取最优Sum[j]。
可以想到单调队列。


代码(CPP)

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e6 + 10;
const int INF = 0x3fffffff;
const int mod = 1000000007;
ll s[maxn], n, m;
deque<ll> q;

void solve() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> s[i];
        s[i] = s[i - 1] + s[i];
    }
    // 暴力解法,求出前缀和之后,用O(n^2)的朴素算法算出每个窗口区间的和,会超时
    // ll ans = -INF;
    // for (int i = 1; i <= n; i++) {
    //     for (int j = i - m + 1; j <= i; j++) {
    //         ans = max(ans, s[i] - s[j - 1]);    // [j, i]的区间和
    //     }
    // }
    // cout << ans << endl;

    /*
        我们考虑在这个朴素解法的基础上进行优化,将上面P[i]的计算式改写为
        P[i] = sum[i] - min{sum[j],  i - m <= k <= i - 1},
        于是我们就要想方设法在优于O(M)的时间内实现获取最小的sum[j]。这个sum[j]必须是[i - m, i - 1]区间内最小的。
        考虑设计这样一个数据结构,在更低的时间复杂度内获取最优Sum[j]。
        可以想到单调队列。
    */
    ll ans = -INF;
    q.push_back(0);     // 这里一定要特别注意,不加这个是会有空队列访问溢出的情况的
    for (int i = 1; i <= n; i++) {
        // 去尾:如果队尾的数字比当前数字大,则出队。保证队列从队头到队尾是递增的。
        while (!q.empty() && s[q.back()] > s[i]) {
            q.pop_back();
        }
        // 入队
        q.push_back(i);
        // 删头:如果队首的数字已经落在了窗口之外,则将其出队.保证窗口大小不超过m。
        while (!q.empty() && q.front() < i - m) {   
            q.pop_front();
        }
        ans = max(ans, s[i] - s[q.front()]);
    }
    cout << ans;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout << fixed;
    cout.precision(18);

    solve();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1321531.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】八大排序之简单选择排序算法

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 一.简单选择排序简介及思路 二.简单选择排序的代码实现 三.简单选择排序的优化 四.简单选择排序的时间复杂度分析 结语 一.简单选择排序简介及思路 简单选择排序算法…

k8s集群内部署nexus

一、前言 在k8s集群中部署nexus服务需要使用到pv、pvc服务来存储nexus的数据&#xff0c;需要使用service服务来提供对外访问nexus服务的端口&#xff0c;需要使用deployment服务来管理nexus服务&#xff0c;接下来就是用这些服务来在k8s集群中搭建nexus&#xff0c;pv服务使用…

C#中HttpWebRequest的用法

前言 HttpWebRequest是一个常用的类&#xff0c;用于发送和接收HTTP请求。在C#中使用HttpWebRequest可以实现各种功能&#xff0c;包括发送GET和POST请求、处理Cookie、设置请求头、添加参数等。本文将深入介绍HttpWebRequest的用法&#xff0c;并给出一些常见的示例。 目录 前…

MATLAB 主成分分析PCA拟合平面点云 (42)

MATLAB 主成分分析PCA拟合平面点云 (42) 一、算法介绍二、算法实现一、算法介绍 主成分分析(Principal Component Analysis,PCA)是一种常用的数据降维和特征提取技术。它的主要思想是通过线性变换将数据投影到一个新的坐标系,使得在新的坐标系中数据的方差最大化。在3D点…

vp与vs联合开发-通过CogAcqFifoTool工具连接相机

1.完成相机硬件配置后 2.完成vp与vs联合开发配置功能后 1.创建winform 项目 目的 : 搭建 界面应用 2. 1. vpp文件存入 项目的debug 目录中 目的&#xff1a; 在项目中加载本地vpp文件 读取相机工具 1.控件CogRecordDisplay 用于显示相机拍摄照片和实施显示的窗口 2和3 …

PostgreSQL的安装、配置与使用指南

文章目录 一、介绍二、安装1、下载安装2、验证 三、配置1、远程连接配置1&#xff09;配置postgresql.conf2&#xff09;配置pg_hba.conf3&#xff09;重启 2、配置数据库的日志 四、图形化界面1、pgAdmin2、Navicat 一、介绍 PostgreSQL是一个功能强大的 开源 的关系型数据库…

[学习笔记]批量迁移数据库文件

拷贝数据库文件 首先在本地运行如下SQL语句&#xff0c;查看数据库文件的磁盘位置 SELECT name, physical_name AS CurrentLocation, state_desc FROM sys.master_files默认是保存在C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA目录下 首先复制数据…

随时随地刷题题库小程序源码系统+完整代码包+安装部署教程

互联网的普及和在线教育的发展&#xff0c;越来越多的人开始利用碎片时间进行学习。为了满足这一需求&#xff0c;随时随地刷题题库小程序应运而生。该小程序提供了一个便捷的刷题平台&#xff0c;用户可以在任何时间、任何地点进行刷题练习&#xff0c;提高自己的学习效率。 …

C# Tcplistener,Tcp服务端简易封装

文章目录 前言相关文章前言设计代码简单使用运行结果 前言 我最近有个需求要写Tcp服务端&#xff0c;我发现Tcp服务端的回调函数比较麻烦&#xff0c;简化Tcp的服务&#xff0c;我打算自己封装一个简单的Tcp服务端。 相关文章 C# TCP应用编程三 异步TCP应用编程 C# Tcpclient…

开源一个超好用的接口Mock工具——Msw-Tools

作为一名前端开发&#xff0c;是不是总有这样的体验&#xff1a;基础功能逻辑和页面UI开发很快速&#xff0c;本来可以提前完成&#xff0c;但是接口数据联调很费劲&#xff0c;耗时又耗力&#xff0c;有时为了保证进度还不得不加加班。 为了摆脱这种痛苦&#xff0c;经过一周的…

uniapp 用于开发H5项目展示饼图,使用ucharts 饼图示例

先下载ucharts H5示例源码&#xff1a; uCharts: 高性能跨平台图表库&#xff0c;支持H5、APP、小程序&#xff08;微信小程序、支付宝小程序、钉钉小程序、百度小程序、头条小程序、QQ小程序、快手小程序、360小程序&#xff09;、Vue、Taro等更多支持canvas的框架平台&#…

掌握电脑开机密码设置技巧,让你的电脑数据更安全!

在现代社会&#xff0c;电脑已经成为了我们日常生活中必不可少的工具。然而&#xff0c;随着科技的发展&#xff0c;我们使用电脑也面临着一些安全隐患。为了保护个人数据的安全&#xff0c;设置开机密码就变得十分重要。本文将为大家介绍电脑怎么设置开机密码&#xff0c;以保…

在RTOS中验证互斥量有效解决优先级反转现象

我们在stm32f103c8t6单片机上验证RTOS互斥量有效解决优先级反转现象&#xff0c;利用stm32cube进行RTOS的配置。在选择TIM2当做RTOS的时钟&#xff0c;裸机的时钟源默认是 SysTick&#xff0c;但是开启 FreeRTOS 后&#xff0c;FreeRTOS会占用 SysTick &#xff08;用来生成1ms…

数组去重及去除指定值,每一个对象添加属性值

1、数组去重ES6写法 Set() // 数组去重 let arr [1,2,4,6,3,2,6,7,7,2,9,0,1,5] arr [...new Set(arr)] console.log(arr); 2、数组去除指定值 filter() // 数组去除指定值 let arr [1,2,4,6,3,2,6,7,7,2,9,0,1,5] const num 7 arr arr.filter(item>item!num) cons…

Go集成elasticsearch8极简demo,光速入门

Go集成elasticsearch8极简demo,光速入门 配置go环境创件go mod工程代码实现配置go环境 编辑器添加goproxy GO111MODULE=on;GOPROXY=https://mirrors.wps.cn/go/,https://goproxy.cn,direct;GOSUMDB=off创件go mod工程 mkdir demo cd demo go mod init demo代码实现 在demo…

测试用例的修改更新

测试用例的修改更新是指测试过程中由于用户需求的改变&#xff0c;或者测试过程中发现有新的需求产生&#xff0c;使得测试用例需要进行修改。修改更新测试用例不仅是一种测试技术&#xff0c;更是一种质量保证的方法。但修改和更新测试用例的技术要点在于&#xff1a; 1、执行…

设计模式之创建型设计模式(一):单例模式 原型模式

单例模式 Singleton 1、什么是单例模式 在软件设计中&#xff0c;单例模式是一种创建型设计模式&#xff0c;其主要目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 这意味着无论何时需要该类的实例&#xff0c;都可以获得相同的实例&#xff0c;而不会创建…

API接口能力不足?Bug处理慢?Lazada开放平台API商品接入

7月30日正式发布的Lazada开放平台2.0&#xff08;Lazada Open Platform 2.0&#xff09;&#xff0c;从商品API、订单API、IM&#xff08;即时通信&#xff09; API、营销工具等几大方向&#xff0c;带来全新升级的API体系&#xff0c;共新增47个接口、优化19个接口&#xff0c…

JVM-9-Class类文件的结构

Java技术能够一直保持着非常良好的向后兼容性&#xff0c;Class文件结构的稳定功不可没。 Class文件是一组以8个字节为基础单位的二进制流&#xff0c;各个数据项目严格按照顺序紧凑地排列在文件之中。 Class文件格式采用一种类似于C语言结构体的伪结构来存储数据&#xff0c…

详细教程 - 从零开发 鸿蒙harmonyOS应用 第八节——鸿蒙操作系统中的文件读写操作封装

一、引言 鸿蒙操作系统是华为自主研发的全场景操作系统。在这篇博客中&#xff0c;我们将探讨如何在鸿蒙操作系统中实现文件读写操作的封装。 二、文件读写操作 在鸿蒙操作系统中&#xff0c;文件读写操作是一个常见的需求。下面是一个简单的文件读写操作的封装示例&#xff1…