P2034 选择数字 / P2627 [USACO11OPEN]Mowing the Lawn G
题目描述
给定一行 \(n\) 个非负整数 \(a[1]..a[n]\) 。现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择。你的任务是使得选出的数字的和最大。
输入格式
第一行两个整数 \(n\) ,\(k\)
以下n行,每行一个整数表示 \(a[i]\)。
输出格式
输出一个值表示答案。
输入输出样例
输入 #1
5 2
1
2
3
4
5
输出 #1
12
说明/提示
对于20%的数据,n <= 10
对于另外20%的数据, k = 1
对于60%的数据,n <= 1000
对于100%的数据,1 <= n <= 100000,1 <= k <= n,0 <= 数字大小 <= 1,000,000,000
时间限制500ms
没错,我又来水题啦。
首先,我们会想到 O(\(n^2\) ) 的dp
设 \(f[i]\) 表示从前 \(i\) 个数的最大价值。
那么就会有转移
\(f[i] = max(f[i], f[i-k-1] + sum[i] - sum[i-k+1-1])\) (后面我拆开写主要是为了好理解,实际上化简一下就可以)。
\(k\) 是我们枚举的要选的连续的数的个数,即区间长度。
这样肯定会 TLE 得啦。
但有没有觉得这个柿子很熟悉,这不就是求 \(i-k-1 , i\) 的最大值。
直接上单调队列优化,记得一开始要把前 \(k\) 个点先入队,在去更新其他的。
我们更新 \(i\) 的时候,要先把 \(i\) 入队在更新,因为他可以取到 \(i\) 也就相当于不选这个数。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define int long long
int n,k,x,head,tail;
int sum[100010],f[100010],q[100010];
inline int read()
{
int s = 0, w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s =s * 10+ch - '0'; ch = getchar();}
return s * w;
}
signed main()
{
n = read(); k = read();
for(int i = 1; i <= n; i++)
{
x = read();
sum[i] = sum[i-1] + x;//维护一个前缀和
}
head = 1, tail = 0;
q[++tail] = 0;
for(int i = 1; i <= k; i++)//先把前k的点入队
{
f[i] = sum[i];
while(head <= tail && f[q[tail] - 1] - sum[q[tail]] <= f[i-1] - sum[i]) tail--;
q[++tail] = i;
}
for(int i = k+1; i <= n; i++)
{
while(head <= tail && q[head] < i - k) head++;//把过期的扔掉
while(head <= tail && f[q[tail]-1] - sum[q[tail]] <= f[i-1] - sum[i]) tail--;//把不优的情况也扔掉
q[++tail] = i; //先入队在更新
f[i] = f[q[head]-1] + sum[i] - sum[q[head]];
}
printf("%lld\n",f[n]);
return 0;
}
另外还有一道双倍经验的题 P2627 [USACO11OPEN]Mowing the Lawn G。
这个题和上面那道题差不多,只不过有个小细节是要让节点先更新在入队(至于为什么自己可以想想)。
P2034 选择数字 / P2627 [USACO11OPEN]Mowing the Lawn G的更多相关文章
- 洛谷P2627 [USACO11OPEN]Mowing the Lawn G (单调队列优化DP)
一道单调队列优化DP的入门题. f[i]表示到第i头牛时获得的最大效率. 状态转移方程:f[i]=max(f[j-1]-sum[j])+sum[i] ,i-k<=j<=i.j的意义表示断点 ...
- P2034 选择数字
P2034 选择数字 题目描述 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 错误日志: longlong ...
- 「单调队列优化DP」P2034 选择数字
「单调队列优化DP」P2034 选择数字 题面描述: 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入格 ...
- P2034 选择数字——线性dp(单调队列优化)
选择数字 题目描述 给定一行 \(n\) 个非负整数 \(a[1]...a[n]\) .现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择.你的任务是使得选出的数字的和最大. 输 ...
- codevs 3327 选择数字
3327 选择数字 时间限制: 1 s 空间限制: 256000 KB 题目描述 Description 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续 ...
- input只读属性 设置和移除 选择数字
设置只读属性 $('#stage').attr("readonly", "readonly"); 移除 只读属性 $("input").r ...
- codevs3327选择数字(单调队列优化)
3327 选择数字 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 给定一行n个非负整数a[1]..a[n].现 ...
- 科普:为什么 String hashCode 方法选择数字31作为乘子
作者:coolblog 此文章转载自:https://segmentfault.com/a/1190000010799123 1. 背景 某天,我在写代码的时候,无意中点开了 String hashC ...
- 选择数字(codevs 3327)
题目描述 Description 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入描述 Input De ...
随机推荐
- 记一些Python(Pymysql)建表、增删改查等基础操作(小白适用)
1.读取sql文件创建数据表 有一个形如下图的sql文件,使用python读取文件并在数据库中创建所有的表. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道 ...
- 【Gin-API系列】Gin中间件之鉴权访问(五)
在完成中间件的介绍和日志中间件的代码后,我们的程序已经基本能正常跑通了,但如果要上生产,还少了一些必要的功能,例如鉴权.异常捕捉等.本章我们介绍如何编写鉴权中间件. 鉴权访问,说白了就是给用户的请求增 ...
- pybind11: C++ 工程如何提供 Python 接口
C/C++ 工程提供 Python 接口,有利于融合进 Python 的生态.现在 Python 在应用层,有其得天独厚的优势.尤其因为人工智能和大数据的推波助澜, Python 现在以及未来,将长期 ...
- lua 优化
彻底解析Android缓存机制——LruCache https://www.jianshu.com/p/b49a111147ee lua:部分常用操作的效率对比及代码优化建议(附测试代码) https ...
- ShaderLab 枚举常量
public enum ZTest { Always = 0, Less = 2, Equal = 3, LEqual ...
- 【jmespath】—3. 进阶 Object Projections
继续,来看Object Projections. 一.Object Projections 上面说的是列表投影,只适用于列表.那么对于json对象,可以用对象投影. 投影最终返回的仍然是个列表,只不过 ...
- Construct a Matrix (矩阵快速幂+构造)
There is a set of matrixes that are constructed subject to the following constraints: 1. The matrix ...
- 3. 站在使用层面,Bean Validation这些标准接口你需要烂熟于胸
乔丹是我听过的篮球之神,科比是我亲眼见过的篮球之神.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免 ...
- 两篇好文 清晰地描述bug 技术总监的忠告
如何清晰的描述一个bug 一个技术总监的忠告 --2020-02-26--
- Ubuntu更换国内源--解决终端下载速度慢的问题
目前我已知的更改国内源的方法基本上就两种,第一种,把/etc/apt/sources.list文件里的源更换一下,改成阿里云或者其它源.第二种,更换在设置中software&updates(软 ...