「单调队列优化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 选择数字的更多相关文章

  1. 「学习笔记」单调队列优化dp

    目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...

  2. 【单调队列优化dp】 分组

    [单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...

  3. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  4. 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 ...

  5. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

  6. Parade(单调队列优化dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    ...

  7. BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP

    BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...

  8. [小明打联盟][斜率/单调队列 优化dp][背包]

    链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...

  9. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

随机推荐

  1. Okapi BM25算法

    引言 Okapi BM25,一般简称 BM25 算法,在 20 世纪 70 年代到 80 年代,由英国一批信息检索领域的计算机科学家发明.这里的 BM 是"最佳匹配"(Best M ...

  2. 【雕爷学编程】MicroPython动手做(08)——零基础学MaixPy之识别颜色

    早上用百度搜了一下“颜色识别”,多少有了一点大致的概念,还是老办法,动手做,多实验,往前走,还请各位老师多多指点. OpenCV(百度百科)是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运 ...

  3. AndroidCamera开发学习笔记01

    概述 Android框架支持设备的相机拍照和录像功能 可以直接调用系统的Camera应用来拍照或录像 也可以利用Adroid系统提供的API开发Camera应用来实现拍照和录像的功能 注意事项 需要硬 ...

  4. 大话微服务(Big Talk in MicroService)

    下面开始分析我的microservice 之旅. what? 是什么 why? 为什么 how? 什么做 1.什么是微服务 microservice 是 SOA(Service-Oriented Ar ...

  5. Ehab and a 2-operation task【数论思想】

    Ehab and a 2-operation task 题目链接(点击) You're given an array aa of length nn. You can perform the foll ...

  6. postgresql中进行备份和回滚的常用sql语句小结

    最近在项目中需要对已有的部分数据库数据进行备份,通过搜索和实践,把常用的sql以及过程记录如下, 1.常用的备份数据库思路,把需要备份的数据放到一个新表中,这个新表的记录与需要备份的表完全一样,然后备 ...

  7. ca69a.cpp_c++_函数匹配(重载确定)

    /*ca69a.cpp_c++_函数匹配(重载确定)#重载确定的三个步骤1.候选函数2.选择可行函数3.寻找最佳匹配(如果有的话)#含有多个形参的重载确定 void f1();void f1(int) ...

  8. snprintf和sprintf区别分析

    目录[-] snprintf函数的返回值 snprintf函数的字符串缓冲 今天在项目中使用snprintf时遇到一个比较迷惑的问题,追根溯源了一下,在此对sprintf和snprintf进行一下对比 ...

  9. C语言实现类

    #ifndef __DEFINE__H__ #define __DEFINE__H__ #define vector3(type) \ typedef struct vector3_##type { ...

  10. java并发编程-线程生命周期

    线程生命周期 现代操作系统在运行一个程序时,会为其创建一个进程.例如,启动一个Java程序,操作系统就会创建一个Java进程.现代操作系统调度的最小单元是线程,也叫轻量级进程(Light Weight ...