http://poj.org/problem?id=3017 (题目链接)

题意

  给出一个数列要求将它分割成许多块,每块的数的和不超过m,要求每块中最大的数之和最小。

Solution

  这道题真的很不错啊。

  可以很快写出dp方程:${f[i]=min(f[j]+max(a[j+1],a[j+2]···a[i]))}$。数据范围太大,我们必须要想办法优化这个方程。${O(n)}$的状态肯定是没办法优化到${O(1)}$了,想想怎么把转移优化到${O(logn)}$甚至${O(1)}$呢?似乎完全不可做的样子。

  终于还是膜拜了题解,发现:${f[i]}$一定是单调不降的。那么我们对于一个最大的数${a[k]}$,只要选择在它的管辖范围内尽可能靠前的点就好了。什么意思呢,就是:

设${a[j+1], a[j+2], ...a[i]}$中值最大的下标为${k}$

设${x}$为${[j+1,k]}$的任意一个下标,则${a[x],a[x+1],....a[i]}$的最大值的下标显然也是k了

由${f}$的非递减性,${f[j+1] + a[k] <= f[j+2]+a[k].....<= f[k - 1] + a[k]}$

很显然,我们只要取${f[j+1]+a[k]}$就可以了。

  于是我们用单调队列记录一个递减的序列${a[k]}$,因为队首不一定是最优,所以我们还要用平衡树记录${a[k]+f[j]}$来维护它。

  当当前${i}$到队首的距离超过m时,pop队首;当即将插入的元素大于队尾元素时,pop队尾。

细节

  multiset的运用。

代码

// poj3017
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<set>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=100010;
int q[maxn],a[maxn],n;
LL m,sum[maxn],f[maxn]; int main() {
scanf("%d%lld",&n,&m);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
multiset<int> s;
int k=0,l=1,r=0;
for (int i=1;i<=n;i++) {
if (a[i]>m) {printf("-1");return 0;}
while (sum[i]-sum[k]>m) k++;
while (l<=r && q[l]<=k)
{if (l<r) s.erase(a[q[l+1]]+f[q[l]]);l++;} //超过m
while (l<=r && a[q[r]]<=a[i])
{if (l<r) s.erase(a[q[r]]+f[q[r-1]]);r--;} //当前a[i]比队尾元素大,pop队尾元素,并在平衡树中删除
q[++r]=i;
if (l<r && i>q[r-1])
s.insert(a[i]+f[q[r-1]]);
int tmp=*s.begin();
f[i]=a[q[l]]+f[k];
if (l<r && tmp<f[i]) f[i]=tmp;
}
printf("%lld",f[n]);
return 0;
}

  

【poj3017】 Cut the Sequence的更多相关文章

  1. 【POJ3017】Cut the Sequence

    题目大意:给定一个长度为 N 的序列,将序列划分成若干段,保证每段之和不超过 M,问所有段的最大值之和最小是多少. 题解:设 \(f[i]\) 表示前 i 个数满足上述条件的最优解,显然有状态转移方程 ...

  2. 【题解】Cut the Sequence(贪心区间覆盖)

    [题解]Cut the Sequence(贪心区间覆盖) POJ - 3017 题意: 给定一大堆线段,问用这些线段覆盖一个连续区间1-x的最小使用线段的数量. 题解 考虑一个这样的贪心: 先按照左端 ...

  3. 【CF486E】LIS of Sequence题解

    [CF486E]LIS of Sequence题解 题目链接 题意: 给你一个长度为n的序列a1,a2,...,an,你需要把这n个元素分成三类:1,2,3: 1:所有的最长上升子序列都不包含这个元素 ...

  4. 【BZOJ4355】Play with sequence 线段树

    [BZOJ4355]Play with sequence Description 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a ...

  5. 【规律】A Rational Sequence

    题目描述 An infinite full binary tree labeled by positive rational numbers is defi ned by:• The label of ...

  6. 【最长下降子序列】【动态规划】【二分】XMU 1041 Sequence

    题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1041 题目大意: 一个二维平面,上面n(n<=1 000 000)个点.问至少选 ...

  7. 【动态规划】XMU 1583 Sequence

    题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1583 题目大意: T组数据,对于n(n<=6000)给定序列Xn(Xn<= ...

  8. 【SPOJ】2319 BIGSEQ - Sequence

    [算法]数位DP [题解]动态规划 题目要求的是大整数……没办法只写了小数字的,感觉应该没错. 大题框架是最大值最小化的二分问题. 对于每一块要求count(b)-count(a-1)≥s 已知a如何 ...

  9. 【leetcode】Longest Consecutive Sequence(hard)☆

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

随机推荐

  1. php中Jpgraph的运用

    用Jpgraph,只要了解它的一些内置函数,可以轻松得画出折线图.柱形图.饼状图等图表. 首先要保证PHP打开了Gd2的扩展: 打开PHP.ini,定位到extension=php_gd2.dll,把 ...

  2. 用Myisamchk让MySQL数据表更健康

    用Myisamchk让MySQL数据表更健康 2011-03-15 09:15 水太深 ITPUB 字号:T | T 为了让MySQL数据库中的数据表“更健康”,就需要对其进行定期体检.在这里笔者推荐 ...

  3. QT QT练习一

    界面中通过三个 QLineEdit控件,一个QPushButton实现+ - * /四则运算,点击pushbutton后将运算结果显示在QLabel控件上. #ifndef WIDGET_H #def ...

  4. Android RecyclerView 使用完全解析 体验艺术般的控件

    概述 RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用. 据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我 ...

  5. VS编译器优化诱发一个的Bug

    VS编译器优化诱发一个的Bug Bug的背景 我正在把某个C++下的驱动程序移植到C下,前几天发生了一个比较诡异的问题. 驱动程序有一个bug,但是这个bug只能 Win32 Release 版本下的 ...

  6. 漫谈 Java 实例化类

    Java 中实例化类的动作,你是否还是一成不变 new 对应对象呢? 经手的项目多了,代码编写量自然会增加,渐渐的会对设计模式产生感觉. 怎样使书写出来的类实例化动作,高内聚,低耦合,又兼具一定的扩展 ...

  7. Google Zxing 二维码生成与解析

    生成二维码的开源项目可谓是琳琅满目,SwetakeQRCode.BarCode4j.Zxing...... 前端有JQuery-qrcode,同样能实现生成二维码. 选择Zxing的原因可能是对 Go ...

  8. WPF 3D模型 3D场景

    1.首先得说明的是这并不是真正的3D,模型被导出为一系列的单个图片,例如一个3D户型图,以某个视角旋转360°,渲染出一系列连续的单个图片文件. 2.在Image.MouseMove事件中添加相应代码 ...

  9. AngularJS中实现无限级联动菜单(使用demo)

    昨天没来得及贴几个使用demo,今天补上,供有兴趣的同学参考 :) 1. 同步加载子选项demo2. 异步加载子选项demo3. 初始值回填demo4. 倒金字塔依赖demo directive的源代 ...

  10. ModernUI教程:定义一个Logo

    ModernWindow的标题栏包含了一块区域用来显示自定义的窗体Logo: 这个窗体logo通过ModernWindow.LogoData属性来设置.这个属性是几何类型数据支持Path.Data m ...