Cut the Sequence(POJ3017)
poj3017
题目大意:给一个长度为n的序列a,要你将其分成若干段,在满足每段和不超过m的情况下,让每段中的最大值之和最小,求最小值。
容易想到动态规划,令f[i]表示把前i个数分段所得的最小值
f[i]=min{f[j]+max (j+1<=k<=i){a[k]}} (a[j+1]+a[j+2]+......+a[i]<=m)
时间复杂度o(n2),我们考虑如何优化。
考虑单调队列,由于f[i]一定是单调不降的,
对于任意两个连续决策j-1,j(0<=j-1<j<i且a[j+1]+a[j+2]+......+a[i]<=m),我们分两种情况:
情况1:若(a[j]+a[j+2]+......+a[i]>m)
此时j-1不符合条件,j有用,优
情况2:若(a[j]+a[j+2]+......+a[i]<=m)
当 存在 f[j-1]+max(j<=k<=i){a[k]} <= f[j]+max(j+1<=k<=i){a[k]}
说明j-1更优,且随着i的增大,j-1更容易满足小于i,所以j为无用决策,应删除。
所以当且仅当 f[j-1]+max(j<=k<=i){a[k]} > f[j]+max(j+1<=k<=i){a[k]} ,j有用.
因为f[j-1]<=f[j]
所以 max(j<=k<=i){a[k]} > max(j+1<=k<=i){a[k]}
所以 a[j]=max(j<=k<=i){a[k]}
综上:若j更优,除了满足(a[j+1]+a[j+2]+......+a[i]<=m)
还应当满足两个条件之一
条件一 a[j]+a[j+2]+......+a[i]>m
条件二 a[j]=max(j<=k<=i){a[k]}
条件一容易处理,考虑条件二,维护一个决策点j单调递增,a[j]单调递减的队列即可。
至于max (j+1<=k<=i){a[k]}如何得到,其实就是队列下一个元素的a值。
但注意到维护的队列对f[j]+max (j+1<=k<=i){a[k]}没有单调性,所以建立一个数据结构,如平衡树set,存f[j]+max (j+1<=k<=i){a[k]},
以便快速得到。(数据太水,直接暴力扫队列竟然还要快一些)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<set> 6 #define ll long long 7 using namespace std; 8 int f[100005],a[100005],q[100005]; 9 int n; 10 ll m,sum[100005]; 11 multiset<int> s; 12 int main() 13 { 14 int i,j; 15 scanf("%d%lld",&n,&m); 16 int L=1,r=0,k=0;//k为队列区间起始位置L的前一个位置 (维护条件2) 17 for(i=1;i<=n;i++)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i]; 18 for(i=1;i<=n;i++) 19 { 20 if(a[i]>m){printf("-1");return 0;} 21 while(sum[i]-sum[k]>m)k++;//维护k 22 while(L<=r&&q[L]<=k) 23 { 24 if(L<r)s.erase(f[q[L]]+a[q[L+1]]);//删去 区间和大于m的候选项 25 L++; 26 } 27 while(L<=r&&a[q[r]]<=a[i]) 28 { 29 if(L<r)s.erase(f[q[r-1]]+a[q[r]]);//维护a[]单调递减 30 r--; 31 } 32 q[++r]=i; 33 if(L<r)s.insert(f[q[r-1]]+a[i]); 34 f[i]=f[k]+a[q[L]];//条件1更新f 35 if(L<r)f[i]=min(f[i],*s.begin());//条件2更新f 36 } 37 printf("%d",f[n]); 38 return 0; 39 }
转载于:https://www.cnblogs.com/dsb-y/p/11008366.html
Cut the Sequence(POJ3017)相关推荐
- EF中创建、使用Oracle数据库的Sequence(序列)功能
** 背景 ** 项目中订单号原来的生成规则由日期加随机数组成,后期需求决定将订单号生成规则更改为生成日期加当天当前订单数. 每天的订单数都是从0开始的,每生成一个订单,订单数就应该加1.订单数应该是 ...
- UVM入门与进阶学习笔记16——sequencer和sequence(2)
目录 sequence的层次化 Hierarchical Sequence Virtual Sequence Layering Sequence sequence的层次化 就水平复用而言,在MCDF各 ...
- Codeforces Round #666 (Div. 2)B. Power Sequence(等比数列)
problem 给出一个数列 两个操作 交换位置或者+1 -1 使数列成为首项为1的等比 求最少操作次数 solution 考虑到等比数列一定递增,直接排序 (过渡)试想特殊情况,排序后如果知道公比, ...
- 【XSY2564】sequence(dp)
题面 [题目描述] 给定一个长度为nnn的由['0'...'9'][\text{'}0\text{'}...\text{'}9\text{'}]['0'...'9']组成的字符串sss,v[i,j]v ...
- Final Cut Pro x(FCPX)调色笔记
文章目录 一.注意点 二.调色流程 1. 颜色校正(一级校色) 1.1 颜色转换即色彩空间转换 1.2 降噪(noise reduction 即NR) 1.3 调整曝光和对比度 1.4 调整白平衡 1 ...
- HDOJ-2062 :Subset sequence(DP)
题目:求子集序列 Consider the aggregate An= { 1, 2, -, n }. For example, A1={1}, A3={1,2,3}. A subset sequen ...
- New Year and Ascent Sequence(二分)
A sequence a=[a1,a2,-,al]a=[a1,a2,-,al] of length ll has an ascent if there exists a pair of indices ...
- HDU 6078 Wavel Sequence (dp)
Description Have you ever seen the wave? It's a wonderful view of nature. Little Q is attracted to s ...
- POJ 1141 Brackets Sequence(动态规划)
题目大意 给你一个括号串(包括'(',')','[',']'),长度不超过 100,问你怎么添加最少的括号,使得这个括号串是合法的,输出添加括号后的合法括号串 做法分析 以长度划分阶段,定义状态:f[ ...
最新文章
- FM:代谢无机硫化合物的古菌Ferroplasma可介导细胞外电子传递
- Linux 入门基础
- ***学习笔记教程五:***技术
- 模拟纳指stock的小例子
- 数据分析:复杂业务场景下,量化评估流程
- iOS 11 正式版发布,都有哪些新内容?
- python中pprint是干什么的_Python中的pprint折腾记
- 图片延迟加载(lazyload)的实现原理
- 9. Linux 磁盘与文件管理系统(inode 目录)
- 疯狂java讲义第六章课后习题答案
- 开发实现物理加速度移动_2019年最受物理老师欢迎的7款软件发布!不要错过!...
- Windows10系统内置的emoji表情
- iframe之嵌套方案总结
- 银河土星_设计师来自土星,开发人员来自木星:或者,为什么沟通很重要
- JS算法-整数转罗马数字
- Oracle 12c 的安装步骤教程
- 企业级分布式批处理方案
- _ViewStart.cshtml介绍
- 禁止windows更新唤醒计算机,windows10睡眠被自动更新唤醒的解决方法
- 视频教程-VUE前端开发/前后端分离-Java
热门文章
- C# 学习笔记(15)自己的串口助手----波形显示
- python编译安装pyaudio
- Given an integer, write a function to determine if it is a power of two
- matlab随机数生成
- [三个版本]自定义int()函数(Python实现)
- 13.6 Thread类自定义线程类
- win8音频服务器未响应,大神为你详解win8系统右键点击文件提示“未响应”的解决教程...
- 提高办公效率的个Excel技巧,告别苦加班!
- 树莓派-格式化硬盘(U盘)为ext4格式并挂载
- 修改anaconda3 jupyter notebook 默认路径