选择数字

题目描述

给定一行 \(n\) 个非负整数 \(a[1]...a[n]\) 。现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择。你的任务是使得选出的数字的和最大。

输入格式

第一行两个整数 \(n\),\(k\) 。

以下 \(n\) 行,每行一个整数表示 \(a[i]\) 。

输出格式

输出一个值表示答案。

输入输出样例

输入

5 2
1
2
3
4
5

输出

12

说明/提示

对于 \(20\%\) 的数据,\(n\leq 10\) 。

对于另外 \(20\%\) 的数据,\(k=1\) 。

对于 \(60\%\) 的数据,\(n\leq 1000\) 。

对于 \(100\%\) 的数据,\(1\leq n\leq 100000\),\(1\leq k\leq n\),\(0\leq 数字大小\leq 1,000,000,000\) 。

时间限制 \(500ms\) 。

数组含义

\(a[i]\): 原数组。

\(sum[i]\): 前缀和,便于计算。

\(dp[i][1/0]\): 前 \(i\) 个数字的状态下,第 \(i\) 个数字选/不选的和的最大值。

\(q[i]\): 在单调数列中第 \(i\) 个数字,在原数组的下标。

基本思路

当第 \(i\) 个数字不选的时候,比较简单,取前 \(i-1\) 的状态选或不选的最大值即可。

\(dp[i][0]=max(dp[i-1][0],dp[i-1][1])\)

当第 \(i\) 个数字选的时候,可以枚举前 \(j\) 个数字的状态,依次取最大值即可。

\(dp[i][1]=max(dp[j][0])-sum[j]+sum[i]\)(伪代码,误抄)

但是本题数据很大,暴力枚举 \(j\) ,效率堪忧。

因为题中可以对 \(a[i]\) 选或不选,在有限制的条件下,\(a[i]\) 肯定越大越好,所以可以用到单调队列进行优化。

(在此提一句,刚开始我想到用贪心,从头枚举,每个区间都正好卡 \(k\) 的长度,但是很明显可以举出反例)

7 3
1 4 1 10000 1 4 1

用到单调队列,就可以把式子改了。

\(dp[i][1]=dp[q[head]][0]-sum[q[head]]+sum[i]\)

最后记得开 \(long long\) 哟。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std; const int maxn=1e6+50;
int n,k;
ll a[maxn];
ll sum[maxn];
ll dp[maxn][2];
ll q[maxn]; int main(){
int head=1;
int tail=1;//这个我测试了一下,必须是1,若为0,则需要进行初始化
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
dp[1][1]=a[1];//tail=0时必加的初始化
for(int i=1;i<=n;i++){
dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
while(q[head]<i-k&&head<=tail){//去掉最先走出队列,而且值也不大的数字
head++;
}
dp[i][1]=dp[q[head]][0]-sum[q[head]]+sum[i];
while(sum[i]-dp[i][0]<sum[q[tail]]-dp[q[tail]][0]&&head<=tail){//若尾端加入的数字,去掉的数字总值比i时还大,则直接去掉
tail--;
}
q[++tail]=i;
}
printf("%lld\n",max(dp[n][1],dp[n][0]));
return 0;
}

P2034 选择数字——线性dp(单调队列优化)的更多相关文章

  1. Mowing the Lawn【线性dp + 单调队列优化】

    题目链接:https://ac.nowcoder.com/acm/contest/2652/G 题目大意:与上一篇博客 烽火传递 差不多. 1.一共n头羊,若超过m头连续的羊在一起,就会集体罢工,每头 ...

  2. [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)

    DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...

  3. Codeforces 1077F2 Pictures with Kittens (hard version)(DP+单调队列优化)

    题目链接:Pictures with Kittens (hard version) 题意:给定n长度的数字序列ai,求从中选出x个满足任意k长度区间都至少有一个被选到的最大和. 题解:数据量5000, ...

  4. Luogu 2627 修建草坪 (动态规划Dp + 单调队列优化)

    题意: 已知一个序列 { a [ i ] } ,求取出从中若干不大于 KK 的区间,求这些区间和的最大值. 细节: 没有细节???感觉没有??? 分析: 听说有两种方法!!! 好吧实际上是等价的只是看 ...

  5. Codeforces 445A Boredom(DP+单调队列优化)

    题目链接:http://codeforces.com/problemset/problem/455/A 题目大意:有n个数,每次可以选择删除一个值为x的数,然后值为x-1,x+1的数也都会被删除,你可 ...

  6. 股票交易(DP+单调队列优化)

    题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi, ...

  7. 3622 假期(DP+单调队列优化)

    3622 假期 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description 经过几个月辛勤的工作,FJ决定让奶牛放假.假期可以在1-N天内任意选择 ...

  8. Codeforces 940 区间DP单调队列优化

    A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...

  9. poj1821 Fence(dp,单调队列优化)

    题意: 由k(1 <= K <= 100)个工人组成的团队应油漆围墙,其中包含N(1 <= N <= 16 000)个从左到右从1到N编号的木板.每个工人i(1 <= i ...

随机推荐

  1. Linux 用户和用户组管理-用户信息文件

    用户信息文件存在在/etc/passwd中,vi /etc/passwd 其中,有七列以:分隔的信息 第一列表示用户(account),第二列表示密码标志(真正的密码存在在/etc/shadow中), ...

  2. Android getMeasuredHeight()与getHeight()的区别

    getMeasuredHeight()返回的是原始测量高度,与屏幕无关 getHeight()返回的是在屏幕上显示的高度 实际上在当屏幕可以包裹内容的时候,他们的值是相等的,只有当view超出屏幕后, ...

  3. mysql 大表mysqldump迁移方案

    场景 一张历史表product_history 500万数据,凌晨的才会将正式表的数据迁移到历史表,此次需求将历史表迁移到一个更便宜的数据库实例进行存储. 条件 1.此表不是实时写,凌晨才会更新 2. ...

  4. excel 如何制作带下拉框的动态折线图表

    首先我们需要有个类似下图产品销量的基础数据表. 首先将光标放入表格中任意位置,然后插入一个不带点标记的折线图,然后将折线的颜色设置为灰色. 第一次设置成灰色后,一定善用f4快捷键进行快速的折线颜色设置 ...

  5. drf之框架基础

    (一)drf基础 全称:django-rest framework 接口:什么是接口.restful接口规范(协议) CBV(基于FBV的基础上形成).CBV生命周期源码----基于restful规范 ...

  6. 【JMeter_22】JMeter逻辑控制器__录制控制器<Recording Controller>

    录制控制器<Recording Controller> 个人感觉录制的脚本缺陷太明显,没有研究过,暂不做介绍,等后续空了研究后再写

  7. 【JMeter_08】JMeter逻辑控制器__While控制器<While Controller>

    While控制器<While Controller> 业务逻辑: 当条件为非false时,执行该节点下的脚本内容,判断条件包括数字.null.空白.字母.符号.true. 当条件为fals ...

  8. iOS开发实践-OOM治理

    概览 说起iOS的OOM问题大家第一想到的应该更多的是内存泄漏(Memory Leak),因为无论是从早期的MRC还是2011年Apple推出的ARC内存泄漏问题一直是iOS开发者比较重视的问题,比如 ...

  9. cb46a_c++_STL_算法_逆转和旋转reverse_rotate函数advance

    cb46a_c++_STL_算法_逆转和旋转reverse_rotateSTL算法--变序性算法reverse() 逆转reverse_copy()一边复制一般逆转rotate()旋转,某个位置开始前 ...

  10. program files (x86)\microsoft visual studio 14.0\vc\include\xtree,如果没有找到,下标溢出了,就报错咯

    ---------------------------Microsoft Visual C++ Runtime Library---------------------------Debug Asse ...