题面

  • 大意:一段长度为n的序列,分成若干段,每段值的总和不能超过m,求各段中最大值加起来的最小值。

其实最朴素的DP还是很好想的,以f[i]表示i及i以前已经分好所需的最小值,a[i]表示i点的值,那么枚举k,k满足

  1. k<i .
  2. \[(\sum^{j <= i }_{j = k+1}a[j] )<= m.
    \]

可用k更新f[i] : $$f[i]=\min(f[k]+\max(a[k+1->i]))$$

时间复杂度为O(n^2 ),明显T了。

那么一定是有很多的冗杂运算了,下面我们就来找出并避免这些运算。

  • 首先\(f[i]一定是单调不降的\),这很显然。

    那么我们可以找出来一些规律,当 \(\max(a[k+1->i])\) 固定时,\(k越小越好\),当\(\max(a[k+1->i])\)改变时,无法直接判断,仍是一种有可能成为最小值的情况,那么其他的k是没有用的,即 $$j1<j2,a[j1]<=a[j2]时,j2无用$$

    到这里已经可以看出来需要\(维护一个单调递减的单调队列\).

    但是单调队列中是a[k]递减,但\({f[k]+\max(a[k+1->i])}\)并不单调,需要用multiset来维护一下,其中\(\max(a[k+1->i])\)其实就是队列中的下一个元素的值,insert(f[k]+a[k的下一个元素])即可,队列与set同时insert和pop(这里的细节较多,后面看代码注释),因为每个k最多入队和出队一次,单调队列均摊O(1),set维护log(N),总时间复杂度O(Nlog(N)).

    看代码:注意数据范围,得开long long。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> pii;
#define mk make_pair
#define ps push_back
#define fi first
#define se second
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9')f=c=='-'?-1:1,c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
return f*x;
}
const int N=1e5+10,inf=0x7fffffff;
long long n,m,f[N],a[N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
n=read(),m=read();
ll x=0,k=1,tp=0;
for(int i=1;i<=n;++i){
a[i]=read();if(a[i]>m)return puts("-1"),0;//不可能情况
}
multiset<ll> s;
deque<ll> q;
for(int i=1;i<=n;++i){
x+=a[i];
while(x>m)x-=a[k++];//保证sum(a[k->i])<=m
while(!q.empty()&&q.front()<k){//在k之前的点不要,pop掉
tp=f[q.front()];q.pop_front();
if(!q.empty())s.erase(tp+a[q.front()]);//当!q.empty()时,说明set里已经放入了\
(a[q.front()]+f[q.front()的上一个元素]),需要pop(tp+a[q.front()]),下面一样。
}
while(!q.empty()&&a[q.back()]<=a[i]){//保证队列单调递减
tp=a[q.back()];q.pop_back();
if(!q.empty())s.erase(tp+f[q.back()]);
}
if(!q.empty())s.insert(f[q.back()]+a[i]);//队列中每两个相邻元素就得insert一次
q.push_back(i);
f[i]=f[k-1]+a[q.front()];//选择了k->i整个区间,\
因为该段区间最大值(a[q.front()])与f[k-1]也构成一对可能解。
if(s.size())f[i]=min(f[i],*s.begin());//注意判空
}
printf("%lld\n",f[n]);
return 0;
}

Cut the Sequence(单调队列DP+set)的更多相关文章

  1. $Poj3017\ Cut\ The\ Sequence$ 单调队列优化$DP$

    Poj   AcWing Description 给定一个长度为N的序列 A,要求把该序列分成若干段,在满足“每段中所有数的和”不超过M的前提下,让“每段中所有数的最大值”之和最小. N<=10 ...

  2. poj3017 Cut the Sequence 单调队列 + 堆 dp

    描述 把一个正数列 $A$分成若干段, 每段之和 不超过 $M$, 并且使得每段数列的最大值的和最小, 求出这个最小值. 题目链接 题解 首先我们可以列出一个$O(n^2)$ 的转移方程 : $F_i ...

  3. POJ 3017 单调队列dp

    Cut the Sequence Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8764   Accepted: 2576 ...

  4. [TyvjP1313] [NOIP2010初赛]烽火传递(单调队列 + DP)

    传送门 就是个单调队列+DP嘛. ——代码 #include <cstdio> ; , t = , ans = ~( << ); int q[MAXN], a[MAXN], f ...

  5. zstu 4237 马里奥的求救——(单调队列DP)

    题目链接:http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4237 这题可以转化为每次可以走g~d+x步,求最大分数,且最大分数的步数最少. ...

  6. 1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP

    1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP 题意 用摄像机观察动物,有两个摄像机,一个可以放在奇数天,一个可以放在偶数天.摄像机在 ...

  7. Cow Hopscotch (单调队列 + DP)

    链接:https://ac.nowcoder.com/acm/contest/1113/K来源:牛客网 The cows have reverted to their childhood and ar ...

  8. vijos P1243 生产产品(单调队列+DP)

      P1243生产产品   描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产 品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器 ...

  9. POJ 1821 单调队列+dp

    题目大意:有K个工人,有n个墙,现在要给墙涂色.然后每个工人坐在Si上,他能刷的最大范围是Li,且必须是一个连续子区间,而且必须过Si,他刷完后能获得Pi钱 思路:定义dp[i][j]表示前i个人,涂 ...

  10. codeforces 1077F2. Pictures with Kittens (hard version)单调队列+dp

    被队友催着上(xun)分(lian),div3挑战一场蓝,大号给基佬紫了,结果从D开始他开始疯狂教我做人??表演如何AKdiv3???? 比赛场上:A 2 分钟,B题蜜汁乱计数,结果想得绕进去了20多 ...

随机推荐

  1. lanczos算法——求解线性方程组时的辅助算法

    lanczos算法 Lanczos算法是一种将对称矩阵通过正交相似变换变成对称三对角矩阵的算法,以20世纪匈牙利数学家Cornelius Lanczos命名. 注意:Lanczos算法只能对" ...

  2. VSCODE远程调试中如何开启X11转发实现APP屏幕转发

    本文所要做的事情不做过多解释,本文前提是使用本地window10上的VScode远程调试Ubuntu上的代码,在该过程中我们需要查看可视化显示,为此我们使用VSCODE插件来实现X11转发. VSco ...

  3. B站基于Apache DolphinScheduler的一站式大数据集群管理平台(BMR)初窥

    一.背景 大数据服务是数据平台建设的基座,随着B站业务的快速发展,其大数据的规模和复杂度也突飞猛进,技术的追求也同样不会有止境. B站一站式大数据集群管理平台(BMR),在千呼万唤中孕育而生.本文简单 ...

  4. 恭喜社区迎来新PMC成员!

    恭喜Apache SeaTunnel社区又迎来一位PMC Member@liugddx!在社区持续活跃的两年间,大家经常看到这位开源爱好者出现在社区的各种活动中,为项目和社区发展添砖加瓦.如今成为项目 ...

  5. CentOS下离线安装gcc环境,图文详细,方法全面

    CentOS下离线安装gcc环境,图文详细,方法全面 下载 方式1:如果有网的虚拟机还没有安装,可以直接 yum install --downloadonly --downloaddir=/root/ ...

  6. JVM指令大全之不太全系列

    一.未归类系列A 此系列暂未归类. 指令码    助记符                            说明0x00         nop                           ...

  7. 【CMake系列】08-debug release特性设置

    在构建的程序版本中,一共有 debug release minisize relwithDebugInfo四种,其中我们主要使用到就是 debug release 两种,这两种存在着一定的不同,deb ...

  8. 安装 MinGW-w64

    简介 MinGW-w64 是 MinGW 项目的 64 位版本.MinGW(Minimalist GNU for Windows)是 GCC 编译套件和 GNU Binutils 移植到 Window ...

  9. Instant exceeds minimum or maximum instant

    使用 Instant.now().plusSeconds("xxxxx")报错  Instant exceeds minimum or maximum instant原因是取值范围 ...

  10. 【YashanDB数据库】YashanDB如何回收表空间

    确认表空间高水位线,是否有可回收空间. select a.tablespace_name,a.high_water_mark,b.user_bytes,b.total_bytes from (SELE ...