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

  这题的DP方程是容易想到的,f[i]=Min{ f[j]+Max(num[j+1],num[j+2],......,num[i]) | 满足m的下界<j<=i },复杂度O(n^2),妥妥的TLE。其实很多都决策都是没有必要的,只要保存在满足m的区间内,num值单调递减的的那些决策。如果遍历的话,一个下降的序列会退化到O(n^2),于是用堆来优化。。。堆优化这里,纠结了很久T_T,,,网上很多代码都是直接用set来处理,但是set在erase元素的都是会把相同的元素都除掉,应该是只erase一个元素,因为相同的元素中其它的可能会存在队列中。。。难道是数据弱了?。。。

 //STATUS:C++_AC_1172MS_1352KB
#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef __int64 LL;
typedef unsigned __int64 ULL;
//const
const int N=;
const int INF=0x3f3f3f3f;
const int MOD=,STA=;
const LL LNF=1LL<<;
const double EPS=1e-;
const double OO=1e15;
const int dx[]={-,,,};
const int dy[]={,,,-};
const int day[]={,,,,,,,,,,,,};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End int num[N],q[N];
int n;
LL m,f[N];
multiset<int> sbt; int main()
{
// freopen("in.txt","r",stdin);
int i,j,l,r,p,ok;
LL sum;
while(~scanf("%d%I64d",&n,&m))
{
l=sum=;r=-;
sbt.clear();
ok=;
for(i=p=;i<=n;i++){
scanf("%d",&num[i]);
sum+=num[i];
while(sum>m)sum-=num[p++];
if(p>i){ok=;break;}
while(l<=r && num[i]>=num[q[r]]){
if(l<r)sbt.erase(f[q[r-]]+num[q[r]]);
r--;
}
q[++r]=i;
if(l<r)sbt.insert(f[q[r-]]+num[q[r]]);
while(q[l]<p){
if(l<r)sbt.erase(f[q[l]]+num[q[l+]]);
l++;
}
f[i]=f[p-]+num[q[l]];
if(l<r)f[i]=Min(f[i],(LL)*sbt.begin());
}
for(;i<=n;i++)
scanf("%d",&j); printf("%I64d\n",ok?f[n]:-);
}
return ;
}

POJ-3017 Cut the Sequence DP+单调队列+堆的更多相关文章

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

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

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

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

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

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

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

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

  5. POJ 3017 DP + 单调队列 + 堆

    题意:给你一个长度为n的数列,你需要把这个数列分成几段,每段的和不超过m,问各段的最大值之和的最小值是多少? 思路:dp方程如下:设dp[i]为把前i个数分成合法的若干段最大值的最小值是多少.dp转移 ...

  6. POJ 3017 Cut the Sequence

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

  7. POJ - 3162 Walking Race 树形dp 单调队列

    POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这 ...

  8. poj3017 Cut the Sequence[平衡树+单调队列优化]

    这里已经讲得很清楚了. 本質上是決策點與區間最大值有一定關係,於是用单调队列来维护决策集合(而不是常规的),然后在决策集合中选取最小值. 然后觉得这题方法还是很重要的.没写平衡树,用优先队列(堆)来维 ...

  9. 【POJ 2823】Sliding Window(单调队列/堆)

    BUPT2017 wintertraining(16) #5 D POJ - 2823 题意 给定n,k,求滑窗[i,i+k-1]在(1<=i<=n)的最大值最小值. 题解 单调队列或堆. ...

随机推荐

  1. const用法

    一.const作用 二.const用法 1.修饰一般常量   修饰符const可以用在类型说明符前,也可以用在类型说明符后. 例如: ; ; 2.修饰常数组  修饰符const可以用在类型说明符前,也 ...

  2. 制作UI纹理(UI Texture)

    什么情况下使用UI Texture UI Texture的功能是在屏幕上显示一张图片,在这一点上它和Sprite有着相似的功能,但是UI Texture会消耗单独的DrawCall去渲染,并会单独加载 ...

  3. C# 操作mongodb 分组

    c#操作mongodb的分组的简单例子: 1.首先要下载c#对应的mongodb驱动,官方下载地址:https://github.com/mongodb/mongo-csharp-driver/rel ...

  4. Js通过原型继承创建子类

    //定义一个有两个方法的类 function Person(){} Person.prototype.married = function(){}; Person.prototype.unmerrie ...

  5. java-development.sh

    vi /etc/profile.d/java-development.sh export JAVA_HOME=/usr/local/java/jdk1..0_55 export JRE_HOME=$J ...

  6. 华为机试题——数组排序,且奇数存在奇数位置,偶数存在偶数位置

    题目要求很简单,就是给你一个数组,对它进行排序,并且排序后,奇数要放在奇数的位置上,偶数要放在偶数的位置上,如果不满足这个规则的话就在数组上填充0 实现代码如下,文中值得注意的一点就是如何判读这个数字 ...

  7. 在MAC中安装Compass的方法 (转)

    在MAC中通过gem命令安装compass时会出异常,原因是compass版本更新了,一些运行时所用到的依赖软件的版本没能得到更新,故而出现错误.例如,用以下命令安装compass: $ gem in ...

  8. POJ 2531 Network Saboteur

    http://poj.org/problem?id=2531 题意 :有N台电脑,每两台电脑之间都有个通信量C[i][j]; 问如何将其分成两个子网,能使得子网之间的通信量最大. 也就是说将所有节点分 ...

  9. java修改远程服务器密码

    积累: 1. echo 用户名:新密码 | chpasswd

  10. [AC自动机]HDOJ3695 Computer Virus on Planet Pandora

    题意:给t.n,t个案例,n个字符串 下面给n+1个字符串,n个互不相同的小串,最后一个是模式串 模式串会出现[qx]的形式,q为数字,x为一个字母 问n个小串在模式串中出现的个数,正着出现.反着出现 ...