修剪草坪 单调队列优化DP

// 修剪草坪.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <cstring>
#include <deque>
using  namespace std;

/*
https://loj.ac/p/10177
http://ybt.ssoier.cn:8088/problem_show.php?pid=1599

原题来自:USACO 2011 Open Gold

在一年前赢得了小镇的最佳草坪比赛后,FJ 变得很懒,再也没有修剪过草坪。现在,新一轮的最佳草坪比赛又开始了,FJ 希望能够再次夺冠。

然而,FJ 的草坪非常脏乱,因此,FJ 只能够让他的奶牛来完成这项工作。FJ 有 N只排成一排的奶牛,编号为 1到 N。
每只奶牛的效率是不同的,奶牛 i 的效率为 Ei。

靠近的奶牛们很熟悉,如果 FJ 安排超过 K只连续的奶牛,那么这些奶牛就会罢工去开派对。
 因此,现在 FJ 需要你的帮助,计算 FJ 可以得到的最大效率,并且该方案中没有连续的超过 K只奶牛。

【输入】
第一行:空格隔开的两个整数 N 和 K;

第二到 N+1 行:第 i+1行有一个整数 Ei。

【输出】
一行一个值,表示 FJ 可以得到的最大的效率值。

【输入样例】
5 2
1
2
3
4
5
【输出样例】
12
【提示】
样例说明:

FJ 有 5
 只奶牛,他们的效率为 1,2,3,4,5。
 他们希望选取效率总和最大的奶牛,但是他不能选取超过 2
 只连续的奶牛。FJ 选择出了第三只以外的其他奶牛,总的效率为 1+2+4+5=12。

数据范围与提示:

对于全部数据,1≤N≤105,0≤Ei≤109。



6 1
4
7
2
0
8
9

10 3
16
28
37
8
47
30
36
6
0
37


237
*/


const int N = 100010;
long long pre[N];
long long dp[N];
int lastZero;
int n, k;


int main()
{
	cin >> n >> k;

	for (int i = 1; i <= n; i++) {
		int t; cin >> t;
		pre[i] = pre[i - 1] + t;
	}
	deque<int> q;
	for (int i = 1; i <= n; i++) {
		/*
		if (i <= k) {
			dp[i] = pre[i];
		}
		else {
			for (int lastzero = i; lastzero >= i - k; lastzero--) {
				dp[i] = max(dp[i], dp[lastzero - 1] + pre[i] - pre[lastzero]);
			}
		}
		*/
		while (!q.empty() && i - q.front() > k) 
			q.pop_front();
		if (q.empty() || i<=k) 
			dp[i] = pre[i];
		else {
			dp[i] = (dp[q.front()-1] - pre[q.front()] + pre[i]);
		}

		while (!q.empty() && (dp[q.back()-1] - pre[q.back()] <= dp[i-1] - pre[i])) 
			q.pop_back();
		q.push_back(i);
	}

	cout << dp[n] << endl;

	return 0;
}

posted on   itdef  阅读(5)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2021-06-20 LeetCode 126. 单词接龙 II
2020-06-20 AcWing 1608. 森林里的鸟 并查集

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示