poj3017 Cut the Sequence 单调队列 + 堆 dp
描述
把一个正数列 $A$分成若干段, 每段之和 不超过 $M$, 并且使得每段数列的最大值的和最小, 求出这个最小值。
题解
首先我们可以列出一个$O(n^2)$ 的转移方程 : $F_i = \min( F_j + \max( A_k ) ) $ $ j < i \&\& j < k <= i$
然后我们可以考虑毒瘤优化。
按照lyd的书中的思路, j 想要成为 可能的最优决策, 必须满足两个条件之一 :
- j 是最小的使 $\sum\limits_{k= j + 1}^ia_k <= M$成立的数
- $\forall k \in [j + 1, i] , A_j>A_k$
可以用反证法来证明。
对于第一个条件,可以在$O(n)$ 时间内求出所有的$j$, 并进行决策。
接着构造一个单调队列, 满足 $j$ 递增, $A_j$ 递减 —— 若 $A[ j_1]< A[j _2]$则不满足第二个性质, 只能由让$j$ 满足第一个条件, 将$ j_1$弹出队列即可。
查询在队列中的最优决策时, 队首不一定就是最有决策, 需要用 STL- set 来储存队列中的 $ F_j + \max(A_k)$ $ j < i && j < k <=i$, 查询set中的最小值并更新答案。
而 $F_j$是已经求出的,最后的问题就是如何快速求出 $\max(A_k)$ 。 单调队列中的 元素 $j$的下一个元素就是要求的$\max(A_k)$。 因为单调队列中$A_j$是递减的。
另外还有许多细节需要注意,看代码吧(
代码
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<set>
#define rep(i,a,b) for( int i = (a); i <= (b); ++i )
#define per(i,a,b) for( int i = (a); i >= (b); --i )
#define rd read()
using namespace std;
typedef long long ll; const int N = 2e5 + 1e4; int n, a[N], q[N];
ll f[N], m; set<ll>st; int read() {
int X = , p = ; char c = getchar();
for(; c > '' || c < ''; c = getchar() ) if( c == '-' ) p = -;
for(; c >= '' && c <= ''; c = getchar() ) X = X * + c - '';
return X * p;
} inline ll cmin( int A ,int B ) {
return A < B ? A : B;
} int main()
{
n = rd;
scanf("%lld",&m);
rep( i, , n ) a[i] = rd;
f[] = ;
int low = , l = , r = ;
ll sum = ;
set<ll>::iterator it;
rep( i, , n ) {
sum += a[i];
while( sum > m ) sum -= a[++low]; // 求出最小的j使得连续一段和不超过m
if( low >= i ) return printf("-1\n"), ;
while( l <= r && q[l] < low ) {//检验队首是否满足连续和不超过m
if( l < r ) st.erase( f[q[l]] + a[q[l+]]);//队列中删除被弹出的答案
l++;
}
while( l <= r && a[q[r]] <= a[i] ) {//使队列递减
if( l < r ) st.erase( f[q[r - ]] + a[q[r]]);
r--;
}
q[++r] = i;
if( l < r ) st.insert( f[q[r - ]] + a[q[r]]);//加入i,这样才能更新出可行的最优答案
f[i] = f[low] + a[q[l]];
if( st.size() ) {
it = st.begin();
f[i] = cmin( *it, f[i]);
}
}
printf("%lld\n", f[n]);
}
poj3017 Cut the Sequence 单调队列 + 堆 dp的更多相关文章
- $Poj3017\ Cut\ The\ Sequence$ 单调队列优化$DP$
Poj AcWing Description 给定一个长度为N的序列 A,要求把该序列分成若干段,在满足“每段中所有数的和”不超过M的前提下,让“每段中所有数的最大值”之和最小. N<=10 ...
- [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)
DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...
- 【优化】单调队列与dp
笔者大概看了一下单调队列对于DP的优化,故撰此文,望有帮助. (dp还是推式子难啊qwq) 例题1. 题目大意:在n个数的序列中,选择数字,使得其连续不超过k个数,且和最大. 本题的方程相对好推:设d ...
- 【转】单调队列优化DP
转自 : http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列是一种严格单调的队列,可以单调递增,也可以单调递减.队 ...
- 单调队列优化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 ...
- 【HDU 3401 Trade】 单调队列优化dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题目大意:现在要你去炒股,给你每天的开盘价值,每股买入价值为ap,卖出价值为bp,每天最多买as ...
- 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) ...
随机推荐
- X86、X64和X86_64区别
x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称 ...
- 温故而知新-mysql的一些语法show,describe,explain,fulltext
1 show show tables; 显示数据库的所有表 show databases; 显示所有数据库 show columns from table; 显示表的所有列 show grants f ...
- JS吧数字转成2进制 8进制16进制数据
; number.toString(); //转成2进制 number.toString();//转成8进制 number.toString();//转成10进制 number.toString(); ...
- delphi IDE RAD 丢失的快捷键 Ctrl+Shift+F
丢失的Ctrl+Shift+F delphi IDE RAD 丢失的快捷键 Ctrl+Shift+F Find inFiles 为什么呢?RAD Berlin安装了cnpack1.1.0.829后文件 ...
- Simple2D-25 精灵动作
精灵动画作用在精灵上,使精灵表现出动画效果.本文将详细说明如何创建一个简单的动作系统,暂时只有 4 中基本的动作——平移.旋转.缩放和 Alpha 变化,并且这些动作能够自由组合,组成串行动作或并行动 ...
- ABAP-面向对象的开发
转载:https://blog.csdn.net/zhongguomao/article/details/70266246 在程序中, 对象的识别和寻址是通过对象引用来实现的,对象引用变量可以访问对象 ...
- ios 获得指定url的cookie
NSArray *myCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage]cookiesForURL:[NSURL URLWithStrin ...
- 【OpenPose-Windows】OpenPose+VS2015+Windows+CUDA8+cuDNN5.1 官方配置教程(转载)
[我的电脑配置] 操作系统:Windows 10 CUDA版本:cuda_8.0.61_win10 cuDNN版本:cudnn-8.0-windows10-x64-v5.1 GPU model:Nvi ...
- varnish--vcl
●Varnish Configuration Language - VCL(varnish配置语言-VCL) Varnish有一个很棒的配置系统,大部分其他的系统使用配置指令,让您打 ...
- SWFUpload乱码问题的解决
目前比较流行的是使用SWFUpload控件,这个控件的详细介绍可以参见官网http://demo.swfupload.org/v220/index.htm 在使用这个控件批量上传文件时发现中文文件名都 ...