洛谷P1714切蛋糕题解

题目描述

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

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

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

形式化地,在数列 {pn} 中,找出一个子段 [l,r](rl+1m),最大化 i=lrpi

题目分析

欸?这题这么简单?这不就暴力枚举左右端点,前缀和数组 O(1) 查询区间和,取最大值不就行了?

嗯……是个好思路,够暴力,但是吧……

对于 20% 的数据,有 1n100
对于 100% 的数据,有 1n5×105

暴力做法好像不太行

考虑优化

1n 枚举右端点r,设此时左端点为l,最后幸运值总和就是sum[r]-sum[l-1]

由于我们要最大化幸运值,因此我们希望sum[l-1]最小

题目中还有一个限制

小 Z 最多只能吃 m(mn) 小块的蛋糕。

因此 rl+1m

所以我们要找到的就是在以r-1为右端点的,长度为m-1的区间中的最小值

这道题至此就被成功的转化为了滑动窗口求最值的问题

可以用单调队列来维护

AC代码

#include<iostream>
#include<deque>

using namespace std;

const int N=500010;

int n,m;
int a[N];
int ans=-2e9;
deque<int> q;

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		a[i]+=a[i-1];
	}
	for(int i=0;i<=n;i++)
	{
		while(!q.empty()&&q.front()<i-m+1)
			q.pop_front();
		while(!q.empty()&&a[q.back()]>a[i])
			q.pop_back();
		q.push_back(i);
		ans=max(ans,a[i]-a[q.front()]);
	}
	cout<<ans<<endl;
	
	return 0;
} 

完结撒花~~~

posted @   OrangeStar*  阅读(188)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示