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) ...
随机推荐
- django-后台sms管理系统的css框架
地址:https://adminlte.io/ 下载代码.使用index.html的页面及相关文件 通过下在线检查adminlte.io的后台的各种模块元素,仿写.
- uva-10050-模拟水题
一个社会研究组织决定通过一组简单的参数来模拟国家政党的行为.第一个参数一个正整数h(叫做罢工参数),用于指示在对应的政党在俩个连续休假之间的平均天数.虽然这个参数太简单了,它不是最完美的参数.但是它还 ...
- UVA127
模拟游戏,规则如下把卡牌一张接一张,从左到右依次摊开,不可以重叠,每当某张卡片和左边(左边第三张)卡片匹配,它就能放到另外一张卡片上,匹配的规则是他们有一样的级别或者花色,在每次移动完成以后,还需要再 ...
- 3. 修改myeclipse工作区间默认编码和jsp的默认编码
1.windows - preferences - General - Workspace 2.windows - preferences - MyEclipse - Files and Editor ...
- Table-Driven Design 表驱动设计
注:本文所有代码来自 http://www.codeproject.com/Articles/42732/Table-driven-Approach 在许多程序中,经常需要处理那些拥有种种色色不同特性 ...
- ajax 实现跨域
ajax本身是不可以跨域的,通过产生一个script标签来实现跨域.因为script标签的src属性是没有跨域的限制的. 其实设置了dataType: 'jsonp'后,$.ajax方法就和ajax ...
- nodejs 获取文件夹中所有文件、图片 名
//获取项目工程里的图片 var fs = require('fs');//引用文件系统模块 var image = require("imageinfo"); //引用image ...
- 第一个gulp程序
说起来惭愧,一直用公司内部的工具,没有用这些红得发紫的东西.今天东抄西拼终于搞出第一个gulp应用.gulp是做什么的,好处在哪儿我不废话了.直入主题吧. 先在D盘下建立一个xxxx目录,然后打开控制 ...
- 如何将Wav文件做到EXE文件里
1)编写.RC文件 ..RC文件是资源的源文件,编译器也就编译这个文件,生成.RES的资源文件 首先在我们的项目子目录中建立一个纯文本文件,起名叫Sound.rc,文件中 有一行,内容为: SOUND ...
- Scripting API Samples
Scripting API Samples Tomáš Matoušek edited this page on Jan 31 · 32 revisions Home API Changes Bu ...