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)相关推荐

  1. EF中创建、使用Oracle数据库的Sequence(序列)功能

    ** 背景 ** 项目中订单号原来的生成规则由日期加随机数组成,后期需求决定将订单号生成规则更改为生成日期加当天当前订单数. 每天的订单数都是从0开始的,每生成一个订单,订单数就应该加1.订单数应该是 ...

  2. UVM入门与进阶学习笔记16——sequencer和sequence(2)

    目录 sequence的层次化 Hierarchical Sequence Virtual Sequence Layering Sequence sequence的层次化 就水平复用而言,在MCDF各 ...

  3. Codeforces Round #666 (Div. 2)B. Power Sequence(等比数列)

    problem 给出一个数列 两个操作 交换位置或者+1 -1 使数列成为首项为1的等比 求最少操作次数 solution 考虑到等比数列一定递增,直接排序 (过渡)试想特殊情况,排序后如果知道公比, ...

  4. 【XSY2564】sequence(dp)

    题面 [题目描述] 给定一个长度为nnn的由['0'...'9'][\text{'}0\text{'}...\text{'}9\text{'}]['0'...'9']组成的字符串sss,v[i,j]v ...

  5. Final Cut Pro x(FCPX)调色笔记

    文章目录 一.注意点 二.调色流程 1. 颜色校正(一级校色) 1.1 颜色转换即色彩空间转换 1.2 降噪(noise reduction 即NR) 1.3 调整曝光和对比度 1.4 调整白平衡 1 ...

  6. HDOJ-2062 :Subset sequence(DP)

    题目:求子集序列 Consider the aggregate An= { 1, 2, -, n }. For example, A1={1}, A3={1,2,3}. A subset sequen ...

  7. 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 ...

  8. 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 ...

  9. POJ 1141 Brackets Sequence(动态规划)

    题目大意 给你一个括号串(包括'(',')','[',']'),长度不超过 100,问你怎么添加最少的括号,使得这个括号串是合法的,输出添加括号后的合法括号串 做法分析 以长度划分阶段,定义状态:f[ ...

最新文章

  1. FM:代谢无机硫化合物的古菌Ferroplasma可介导细胞外电子传递
  2. Linux 入门基础
  3. ***学习笔记教程五:***技术
  4. 模拟纳指stock的小例子
  5. 数据分析:复杂业务场景下,量化评估流程
  6. iOS 11 正式版发布,都有哪些新内容?
  7. python中pprint是干什么的_Python中的pprint折腾记
  8. 图片延迟加载(lazyload)的实现原理
  9. 9. Linux 磁盘与文件管理系统(inode 目录)
  10. 疯狂java讲义第六章课后习题答案
  11. 开发实现物理加速度移动_2019年最受物理老师欢迎的7款软件发布!不要错过!...
  12. Windows10系统内置的emoji表情
  13. iframe之嵌套方案总结
  14. 银河土星_设计师来自土星,开发人员来自木星:或者,为什么沟通很重要
  15. JS算法-整数转罗马数字
  16. Oracle 12c 的安装步骤教程
  17. 企业级分布式批处理方案
  18. _ViewStart.cshtml介绍
  19. 禁止windows更新唤醒计算机,windows10睡眠被自动更新唤醒的解决方法
  20. 视频教程-VUE前端开发/前后端分离-Java

热门文章

  1. C# 学习笔记(15)自己的串口助手----波形显示
  2. python编译安装pyaudio
  3. Given an integer, write a function to determine if it is a power of two
  4. matlab随机数生成
  5. [三个版本]自定义int()函数(Python实现)
  6. 13.6 Thread类自定义线程类
  7. win8音频服务器未响应,大神为你详解win8系统右键点击文件提示“未响应”的解决教程...
  8. 提高办公效率的个Excel技巧,告别苦加班!
  9. 树莓派-格式化硬盘(U盘)为ext4格式并挂载
  10. 修改anaconda3 jupyter notebook 默认路径