dp+单调性+平衡树

在看某篇论文中看到这道题,但是那篇论文不如这个http://www.cnblogs.com/staginner/archive/2012/04/02/2429850.html 大神的空间写的好(还是说我太弱需要详解……)。

其实要说的在大神的博客里面已经说的很好……

比如f[i],然后j表示满足a[j+1]+a[j+2]+……+a[i]<=m的最小值。然后我们假定a[j]--a[i]中最大数的下标为k,那么就有j+1<=l<=k时,f[j+1]+a[k]<=f[j+2]+a[k]<=f[j+3]+a[k]……<=f[k-1]+a[k],也就是只要在把在k前或者k到i的区间分为一个区间,那么这个区间的最大值就是a[k]。这样f数组就是递增的。


var
left,right,s,q,d:array[..]of longint;
key,a,sum,f:array[..]of int64;
i,j,k,l,n,tot,t,head,tail,deci:longint;
m:int64; procedure rightrotate(var t:longint);
var
k:longint;
begin
k:=left[t];
left[t]:=right[k];
right[k]:=t;
s[k]:=s[t];
s[t]:=s[left[t]]+s[right[t]]+;
t:=k;
end; procedure leftrotate(Var t:longint);
var
k:longint;
begin
k:=right[t];
right[t]:=left[k];
left[k]:=t;
s[k]:=s[t];
s[t]:=s[left[t]]+s[right[t]]+;
t:=k;
end; procedure maintain(var t:longint);
begin
if s[left[left[t]]]>s[right[t]] then begin
rightrotate(t);
maintain(right[t]);
maintain(t);
end;
if s[right[left[t]]]>s[right[t]] then begin
leftrotate(left[t]);
rightrotate(t);
maintain(left[t]);
maintain(right[t]);
maintain(t);
end;
if s[right[right[t]]]>s[left[t]] then begin
leftrotate(t);
maintain(left[t]);
maintain(t);
end;
if s[left[right[t]]]>s[left[t]] then begin
rightrotate(right[t]);
leftrotate(t);
maintain(left[t]);
maintain(right[t]);
maintain(t);
end;
end; procedure insert(var t:longint;v:int64);
begin
if t= then begin
inc(tot);
t:=tot;
key[t]:=v;
s[t]:=;
left[t]:=;
right[t]:=;
end
else begin
inc(s[t]);
if v<key[t] then insert(left[t],v)
else insert(right[t],v);
maintain(t);
end;
end; function delete(var t:longint;v:int64):int64;
begin
dec(s[t]);
if (key[t]=v) or( (v<key[t]) and (left[t]=) )or ((v>=key[t]) and (right[t]=)) then begin
delete:=key[t];
if (left[t]=) or (right[t]=) then
t:=left[t]+right[t]
else key[t]:=delete(left[t],key[t]+);
end
else
if v<key[t] then
delete:=delete(left[t],v)
else delete:=delete(right[t],v);
end; function searchmin(var t:longint):int64;
begin
if left[t]= then exit(key[t]);
exit(searchmin(left[t]));
end; function into:boolean;
begin
readln(n,m);
sum[]:=;
for i:= to n do begin
read(a[i]);
sum[i]:=sum[i-]+a[i];
if a[i]>m then exit(false);
end;
exit(true);
end; begin
if into then begin
t:=;
tot:=;
head:=;
tail:=;
deci:=;
for i:= to n do begin
while sum[i]-sum[deci]>m do inc(deci);
while (head<tail) and (q[head]<=deci) do begin
delete(t,f[d[head]]+a[q[head]]);
inc(head);
end;
while (head<tail) and (a[i]>=a[q[tail-]]) do begin
delete(t,f[d[tail-]]+a[q[tail-]]);
dec(tail);
end;
q[tail]:=i;
if head<tail then
d[tail]:=q[tail-]
else d[tail]:=deci;
insert(t,f[d[tail]]+a[i]);
inc(tail);
if d[head]<deci then begin
delete(t,f[d[head]]+a[q[head]]);
d[head]:=deci;
insert(t,f[deci]+a[q[head]]);
end;
f[i]:=searchmin(t);
end;
writeln(f[n]);
end
else writeln('-1');
readln;
readln;
end.

【以前的空间】Poj 3071 Cut the Sequence的更多相关文章

  1. poj 3017 Cut the Sequence(单调队列优化DP)

    Cut the Sequence \(solution:\) 这道题出的真的很好,奈何数据水啊! 这道题当时看得一脸懵逼,说二分也不像二分,说贪心也不像贪心,说搜索吧这题数据范围怎么这么大?而且这题看 ...

  2. POJ 3017 Cut the Sequence

    [题目链接] $O(n^2)$ 效率的 dp 递推式:${ dp }_{ i }=min\left( dp_{ j }+\overset { i }{ \underset { x=j+1 }{ max ...

  3. poj 3017 Cut the Sequence(单调队列优化 )

    题目链接:http://poj.org/problem?id=3017 题意:给你一个长度为n的数列,要求把这个数列划分为任意块,每块的元素和小于m,使得所有块的最大值的和最小 分析:这题很快就能想到 ...

  4. POJ 3017 Cut the Sequence (单调队列优化DP)

    题意: 给定含有n个元素的数列a,要求将其划分为若干个连续子序列,使得每个序列的元素之和小于等于m,问最小化所有序列中的最大元素之和为多少?(n<=105.例:n=8, m=17,8个数分别为2 ...

  5. 刷题总结——Cut the Sequence(POJ 3017 dp+单调队列+set)

    题目: Description Given an integer sequence { an } of length N, you are to cut the sequence into sever ...

  6. [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)

    DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...

  7. POJ3017 Cut the Sequence

    题意 Language:Default Cut the Sequence Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 122 ...

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

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

  9. 【POJ 3071】 Football(DP)

    [POJ 3071] Football(DP) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4350   Accepted ...

随机推荐

  1. Ruby & Rails学习资料

    ------------------教程------------- Ruby风格指南(代码规范) https://github.com/bbatsov/ruby-style-guide 笨方法學 Ru ...

  2. uvaoj 10474 - Where is the Marble?(sort+lower_bound)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  3. hdu1257最少拦截系统(暴力)

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  4. Xpath语法&示例

    一.选取节点常用的路径表达式: 表达式 描述 实例   nodename 选取nodename节点的所有子节点 xpath(‘//div’) 选取了div节点的所有子节点 / 从根节点选取 xpath ...

  5. C#使用EF连接PGSql数据库

    前言 由于项目需要,使用到了PGSql数据库,说实话这是第一次接触并且听说PGSql(PostgreSQL)关系型数据库,之前一直使用的都是SqlServer,一头雾水的各种找资源,终于将PGSql与 ...

  6. git 从头开始

    下载安装git 打开git,输入以下命令,引号内的为你自己的名字和邮箱 git config --global user.name "Your Name"git config -- ...

  7. Java进阶知识点:协变与逆变

    一.背景 要搞懂Java中的协办与逆变,不得不从继承说起,如果没有继承,协变与逆变也天然不存在了. 我们知道,在Java的世界中,存在继承机制.比如MochaCoffee类是Coffee类的派生类,那 ...

  8. 【shell 练习1】编写Shell条件句练习

    实例一.比较两个整数大小 #!/bin/bash while true do read -p "Please input two int nums:" a b >/dev/& ...

  9. Linux下安装paramiko

    paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 由于使用的是python这样的能够跨平台运行的语言,所以所有python支持的平台, ...

  10. 动态内存&对象

    一.对象的生存期 对于 static 对象和自动对象,它们都有着严格定义的生存期. 全局对象:在程序启动时分配,在程序结束时销毁. 局部自动对象:在对象定义语句时分配,在离开块时销毁 局部 stati ...