【单调队列优化dp】 分组
【单调队列优化dp】 分组
>>>>题目
【题目】
给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择。你的任务是使得选出的数字的和最大
【输入格式】
第一行两个整数 n,k,如题目描述
接下来一行n 个数,表示这个序列
【输出格式】
输出一行一个数,表示最大的和
【输入样例】
5 2
1 2 3 4 5
【输出样例】
12
【数据范围与约定】
对于20%的数据,保证1 <=n <=10。
对于40%的数据,保证1 <=n <=200。
对于60%的数据,保证1 <=n <=100000。
对于100%的数据,保证1 <=n <=2000000,1<=K<=n。
>>>>分析
因为题目给出非负整数,根据贪心,我们尽量多选择长度为k的序列
数据范围很大,暴力求每一段的和的做法肯定会T掉,那么考虑dp
题目涉及到求区间和,我们预处理出前缀和,用O(1)复杂度求出区间和
定义:dp[i]表示前i个人的最大收益,sum[i]表示前缀和
现在选的这一段区间和用sum[i]-sum[j]表示(i-k<=j<=i)
这段区间与 前一段长为k的区间 中间要空一个数(不能连续选k+1个数),于是我们固定i点,不断地枚举j点,找到和的最大值
因为sum求的是闭区间的前缀和 , sum[i]-sum[i]表示区间[ j+1 ,i ]的和,中间空的数就是j,再加上dp[j-1]就可以更新dp[i]的值
综上,我们可以得到状态转移方程
dp[i]=max( dp[j-1]+sum[i]-sum[j]) (i-k<=j<=i)
这里的max是对应每一个j点算出括号里的值,再求最大值
那么又怎么算最大值呢?总不能真的枚举j再找最大值吧?肯定不行,时间复杂度太高
但是你会突然发现
原方程可以拆分成 dp[i]=max(dp[j-1]-sum[j])+sum[i]
然后我们可以发现这个式子的变化与sum[i]无关,因为我们固定了i点,只是j点在变
那么我们考虑一个超棒的家伙——单调队列优化
(注意一下单调队列里面存的是下标)
定义f[j]=dp[j-1]-sum[j],将f[j]丢进单调队列里面,每次取出队首元素
扩展下一个点的时候,更新一下:f[i+1]=dp[i]-sum[i+1](和上面的式子是一样的),将它丢进单调队列里面就好啦
ヾ(๑╹◡╹)ノ"
>>>>代码
- #include<bits/stdc++.h>
- #define maxn 2000005
- #define ll long long
- using namespace std;
- int head=,tail=,n,k;
- ll dp[maxn],f[maxn],sum[maxn];
- int a[maxn],q[maxn];
- int read()
- {
- int x= ; char c=getchar() ;
- while(c<''||c>'') c=getchar() ;
- while(c>=''&&c<='') { x=x*+c-'', c=getchar() ; }
- return x;
- }
- int main()
- {
- // freopen("group.in","r",stdin);
- // freopen("group.out","w",stdout);
- scanf("%d%d",&n,&k);
- for(int i=;i<=n;i++)
- {
- a[i]=read();
- sum[i]=sum[i-]+a[i];
- }
- for(int i=;i<=n;i++)
- {
- while(head<tail&&i-q[head]>k) head++;//如果队首的元素已经不在范围里,踢出队列
- dp[i]=f[q[head]]+sum[i];//取出队首元素,更新dp[i]的值
- f[i+]=dp[i]-sum[i+];//更新 f[i+1]
- while(head<tail&&f[q[tail-]]<f[i+]) tail--;//维护单调队列,将小于f[i+1]的数都踢出去
- q[tail++]=i+;
- }
- printf("%I64d",dp[n]);
- return ;
- }
>>>>总结
通过这道题目,我们还可以知道
对于一类dp,状态转移方程抽象为:dp[i]=max(f[j])+g[i] (l[i]<=j<=r[i])
并且l[i]~r[i]单调不减时,我们都可以考虑用单调队列优化
步骤:踢出过时元素,更新dp值,新元素入队并且维护单调队列
那么就到这里啦!
完结撒花٩(๑❛ᴗ❛๑)۶
题目来源: 2019.2.19杨雅儒学长的考试题
【单调队列优化dp】 分组的更多相关文章
- 单调队列优化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 ...
- BZOJ1791[Ioi2008]Island 岛屿 ——基环森林直径和+单调队列优化DP+树形DP
题目描述 你将要游览一个有N个岛屿的公园.从每一个岛i出发,只建造一座桥.桥的长度以Li表示.公园内总共有N座桥.尽管每座桥由一个岛连到另一个岛,但每座桥均可以双向行走.同时,每一对这样的岛屿,都有一 ...
- P4381 [IOI2008]Island(基环树+单调队列优化dp)
P4381 [IOI2008]Island 题意:求图中所有基环树的直径和 我们对每棵基环树分别计算答案. 首先我们先bfs找环(dfs易爆栈) 蓝后我们处理直径 直径不在环上,就在环上某点的子树上 ...
随机推荐
- A Simple Nim (SG打表找规律)
题意:有n堆石子,每次可以将其中一堆分为数量不为0的3堆,或者从其中一堆中拿走若干个,最终拿完的那个人赢. 思路:直接暴力SG状态,然后找出其中的规律,异或一下每一堆的状态就可以了. #include ...
- linux安装sz && rz功能
[1]编译安装 root 账号登陆后,依次执行以下命令: cd /tmp wget http://www.ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz . ./c ...
- MariaDB与MySQL
一.MariaDB安装部署 tar zxvf mariadb-5.5.31-linux-x86_64.tar.gz mv mariadb-5.5.31-linux-x86_64 /usr/local/ ...
- fiddler 抓包工具(新猿旺学习总结)
安装抓包工具 Fiddler 直接安装 fiddler下载连接:https://www.lanzous.com/i30k09c 设置 fiddler 因为 r fiddler 是抓取 P HTTP 和 ...
- 转载-《Python学习手册》读书笔记
转载-<Python学习手册>读书笔记 http://www.cnblogs.com/wuyuegb2312/archive/2013/02/26/2910908.html
- JZ2440学习笔记之第一个裸机程序(Keil-MDK)
CPU:S3C2440, ARM920T, Internal 4KB RAM, Support boot from NAND flash, 128MB for each bank. JZ2440:Me ...
- Pandas截取列部分字符,并据此修改另一列的数据
#截取'股票代码'第一个字符 df['首字符'] = df['股票代码'].str[0:1] ' # 根据'首字符'列的值,修改'市场'的值. 1表示上海 截取字符串的部分字符: date=today ...
- wordpress安装教程
最近安装了wordpress来搭建自己的网站,过程有些艰辛,以防以后转移服务器再次遇到这个难题,在此记下自己的这次安装过程以及一些问题,同时也供遇到相同问题的初次接触者做参考. 另外说明一下我用的操作 ...
- LGOJ P3834 【模板】可持久化线段树 1(主席树)
代码 #include <cstdio> #include <iostream> #include <algorithm> using namespace std; ...
- logstash filter geoip 转换IP为详细地址等内容。
使用logstash geoip筛选器可以将ip地址解析为更丰富的内容. 结果类似于这样: "geoip": { "city_name": "Ürüm ...