「单调队列优化DP」P2034 选择数字
「单调队列优化DP」P2034 选择数字
题面描述:
给定一行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
解法
一般正常求序列几段和都要求前缀和,f的第一维都是前i项的最优值
那我们直接开始吧,
f[i]=max(f[j])+a[i] ( i-k<=j<i )
然鹅叫上去可能只对两个点(可能连样例都不过),原因是方程都错了,少了一维,i不一定选取就是最佳选择,如1 8 4 2 999 k=2,显然不选4要更优, 所以正确的转移方程:
//0表示不选第i个数,1表示选第i个数
f[0][i]=max(f[0][i-1],f[1][i-1]);
f[1][i]=max(f[0][j]-sum[j])+sum[i];
亲测O(n*n)
+快读能压线过
所以考虑优化
我们用单调队列维护f[0][j]-sum[j]的最优值,因为它完全符合单调性,维护就完事
代码:
/*#!/bin/sh
dir=$GEDIT_CURRENT_DOCUMENT_DIR
name=$GEDIT_CURRENT_DOCUMENT_NAME
pre=${name%.*}
g++ -O2 $dir/$name -o $pre -g -Wall -std=c++11
if test $? -eq 0; then
gnome-terminal -x bash -c "time $dir/$pre;echo;read;"
fi*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1e6+5,INF=0x3f3f3f3f;
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;
}
int n,d,a[maxn],head=1,tail;
long long sum[maxn],f[2][maxn],q[maxn];//每个数有1e9诶
int main(){
n=read();d=read();
for(int i=1;i<=n;i++)a[i]=read(),sum[i]=sum[i-1]+a[i];
f[1][1]=a[1];tail++;//tail=0需要初始化,tail=1就不需要,推荐写tail=0
for(int i=2;i<=n;i++){
f[0][i]=max(f[0][i-1],f[1][i-1]);//不选第i个数的情况
while(head<=tail&&i-q[head]>d)head++;//维护队首,i-k>j(q[head])
f[1][i]=f[0][q[head]]-sum[q[head]]+sum[i];
while(head<=tail&&f[0][i]-sum[i]>f[0][q[tail]]-sum[q[tail]])tail--;//维护队列单调性,新数大于原数就出队
q[++tail]=i;
}
cout<<max(f[0][n],f[1][n]);
}
「单调队列优化DP」P2034 选择数字的更多相关文章
- 「学习笔记」单调队列优化dp
目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...
- 【单调队列优化dp】 分组
[单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- bzoj1855: [Scoi2010]股票交易--单调队列优化DP
单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...
- hdu3401:单调队列优化dp
第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...
- Parade(单调队列优化dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others) ...
- BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP
BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...
- [小明打联盟][斜率/单调队列 优化dp][背包]
链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...
- 单调队列以及单调队列优化DP
单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...
随机推荐
- Linux 文件特殊权限-Sticky BIT
SBIT粘着位作用 只对目录有效 普通用户对该目录拥有w和x权限,即普通用户可以在此目录有写权限 如果没有粘着位,普通拥有写权限,就可以删除目录下所有文件,包括其他用户创建的文件,一旦有粘着位,只有r ...
- python numpy 库
引用文章:https://blog.csdn.net/xjl271314/article/details/80409034
- opencl(7) 内核执行命令入队]工作组、工作项
1:将内核执行命令入队(该命令可被多个工作项执行) cl_int clEnqueueNDRangeKernel( cl_command_queue command_queue, cl_kernel k ...
- pom.xml 文件详解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- (一)DB、DBMS、SQL之间的关系
一.概念 DB:数据库(database)相当于一个仓库,用于有组织的采存储数据. DBMS:数据库管理系统(database manage system)数据库是通过DBMS来创建和操作,种类很多( ...
- Spring源码系列(一)--详解介绍bean组件
简介 spring-bean 组件是 IoC 的核心,我们可以通过BeanFactory来获取所需的对象,对象的实例化.属性装配和初始化都可以交给 spring 来管理. 针对 spring-bean ...
- Jmeter基础001----jmeter的安装与配置
一.Java环境安装 1.下载jdk----oracal官网 2.JDK版本要求: JMeter2.x- jdk1.6 ...
- cb10a_c++_顺序容器的操作3关系运算符
cb10a_c++_cb09a_c++_顺序容器的操作3 2 顺序容器的操作3 3 关系运算符 4 所有的容器类型都可以使用 5 比较的容器必须具有相同的容器类型,double不能与int作比较 6 ...
- 容器技术之Docker-swarm
前文我聊到了docker machine的简单使用和基本原理的说明,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13160915.html:今天我们来聊一聊d ...
- selenium3.0-selenium发展史