BZOJ-5424: 烧桥计划(单调队列)

题目链接

题解:

先考虑最暴力的\(dp\):设\(f[k][i]\)表示搞掉第\(1\sim i\)段,烧了\(k\)段的最小花费,设\(calc(x,y)=sum[x\sim y]\le M?0:sum[x\sim y]\),可以列出转移方程如下

\[f[k][i]=min(f[k-1][j]+calc(j+1,i))+k*a[i] (j<i)
\]

这样时间复杂度是\(O(n^3)\)的,十分爆炸

考虑优化

首先发现题目中给出的\(1000 \le a[i]\le 2000\)。仔细想想,这表明\(k\)值最大不会太大

设最坏情况下取了\(k\),则此时一定是满足\(k*(k+1)/2*1000\le n*2000\)的

(就是说不是你把\(n\)段桥都断了也比\(k\)段优)

这样算下来\(n\)最大的时候\(k\)也就是\(600\)的样子,\(O(n*k)\)就可以过了

但现在时间复杂度还是\(O(n^2k)\)的,考虑对于每个\(k\)的每个\(i\),如何快速计算此时的\(f[k][i]\)

这个时候就可以用单调队列优化了。

设当前是\(f[k][i]\),题目中\(M\)的限制(就是那个\(calc(x,y)\))就相当于把\(1\sim i\)段分成了两部分:

前半部分要计算中间的\(sum[x\sim y]\),后半部分不用

那么对于前半部分记一个最小值,后半部分维护递增的单调队列,\(dp\)时取两个最小的那个就可以做到\(O(1)\)转移了

细节不少,刚开始写感觉很迷,写着写着也就想明白了吧

注意\(k\)是没有单调性的,一定从\(1\)到\(T\)全枚举一遍

和\(sxz\)一起卡了波时间,惊奇地发现\(k\)最大居然只有\(152\)

(别问为什么这么准,二分试出来的)

代码:

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define qmax(x,y) (x=max(x,y))
#define qmin(x,y) (x=min(x,y))
#define mp(x,y) make_pair(x,y)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
inline int read(){
int ans=0,fh=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
ans=ans*10+ch-'0',ch=getchar();
return ans*fh;
}
const int maxn=1e5+100;
int n,m,mx,q[maxn],p[maxn],l,r,a[maxn],f[2][maxn];
int tot,mn,sum[maxn],Ans=0x7fffffff;
int main(){
// freopen("nh.in","r",stdin);
// freopen("zhy.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();a[++n]=0;
for(int i=1;i<=n;i++) sum[i]=a[i]+sum[i-1];
int k=0,o=0,lc;
memset(f,0x3f,sizeof(f));
f[0][0]=f[1][0]=0;
int T=min(152,(int)sqrt(n*4));
while(T--){
l=1,r=1,k++,tot=0,mn=0,lc=0;
o^=1,q[1]=p[1]=0;
for(int i=1;i<=n;i++){
int now=0x7fffffff;
while(l<=r&&sum[i-1]-sum[q[l]]>m) l++;
while(1){
if(sum[i-1]-sum[lc]<=m) break;
qmin(mn,f[o^1][lc]+sum[i-1]-sum[lc]-tot);
lc++;
}
if(l<=r) qmin(now,p[l]);
qmin(now,mn+tot);
f[o][i]=(now+=k*a[i]);
while(l<=r&&p[r]>=f[o^1][i]) r--;
p[++r]=f[o^1][i],q[r]=i;
tot+=a[i];
}
qmin(Ans,f[o][n]);
}
printf("%d\n",Ans);
return 0;
}

BZOJ-5424: 烧桥计划(单调队列)的更多相关文章

  1. BZOJ 5424: 烧桥计划

    BZOJ 5424: 烧桥计划 目前暂居rk1QAQ 首先,设\(f[i][k]\)为前i个点中,选了第i个点,总共选了k个点的答案.那么就有: \[f[i][k]=min_{j<i}\{f[j ...

  2. BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP

    BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...

  3. BZOJ 1047 理想的正方形(单调队列)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1047 题意:给出一个n*m的矩阵.在所有K*K的子矩阵中,最大最小差值最小的是多少? 思 ...

  4. bzoj 3831 Little Bird (单调队列优化dp)

    /*先贴个n*n的*/ #include<iostream> #include<cstdio> #include<cstring> #define maxn 100 ...

  5. BZOJ 1499 NOI2005 瑰丽华尔兹 单调队列

    题目大意:给定一个m*n的地图,一些点有障碍物,钢琴初始在一个点,每一个时间段能够选择向给定的方向移动一段距离,求最长路径长 朴素DP的话,我们有T个时间段,每一个时间段有m*n个点,n个时间,一定会 ...

  6. BZOJ 1012: [JSOI2008]最大数maxnumber 单调队列/线段树/树状数组/乱搞

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 4750  Solved: 2145[Submi ...

  7. BZOJ 1791 岛屿(环套树+单调队列DP)

    题目实际上是求环套树森林中每个环套树的直径. 对于环套树的直径,可以先找到这个环套树上面的环.然后把环上的每一点都到达的外向树上的最远距离作为这个点的权值. 那么直径一定就是从环上的某个点开始,某个点 ...

  8. bzoj 3126: [Usaco2013 Open]Photo——单调队列优化dp

    Description 给你一个n长度的数轴和m个区间,每个区间里有且仅有一个点,问能有多少个点 Input * Line 1: Two integers N and M. * Lines 2..M+ ...

  9. bzoj 1499 [NOI2005]瑰丽华尔兹——单调队列优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1499 简单的单调队列优化dp.(然而当时却WA得不行.今天总算填了坑) 注意滚动数组赋初值应 ...

随机推荐

  1. hdu4691(后缀数组)

    算是后缀数组的入门题吧. 思路无比简单,要是直接套模板的话应该很容易秒掉. 关于后缀数组看高中神犇的论文就可以学会了 算法合集之<后缀数组——处理字符串的有力工具> 话说这题暴力是可以过了 ...

  2. bunoj 13124(数位dp)

    数位dp每次都给我一种繁琐的感觉.. A - Palindromic Numbers Time Limit:2000MS     Memory Limit:32768KB     64bit IO F ...

  3. 160801、BlockingQueue处理多线程

    前面介绍过spring的taskExecutor,今天介绍一个jdk里处理多线程的方法 一.spring的配置文件(注入bean) <bean id="cmsClickButtonMn ...

  4. 【IDEA】单元测试:项目中引入JUnit测试框架+Mock简单了解

    一.Junit 使用和说明: 参考:单元测试第三弹--使用JUnit进行单元测试-HollisChuang's Blog http://www.hollischuang.com/archives/17 ...

  5. 第二课——解析mysqldump命令和mysqlbinlog命令+innodb和Myisam存储引擎简介

    环境说明 mysql版本:Percona-Server-5.6.30 IP:10.7.15.167 端口:3306 安装目录:/httx/run/mysql 数据目录:/httx/run/mysql/ ...

  6. Storm的组件

    摘自网上 当时写的很好,很详细的介绍了各个组件直接的关系 Storm集群和Hadoop集群表面上看很类似.但是Hadoop上运行的是MapReduce jobs,而在Storm上运行的是拓扑(topo ...

  7. 机器被感染病毒文件zigw的处理流程

    1.现象 服务器CPU报警,查看时,已接近100%. 2.查找 使用top查看是哪个进程在占用CPU,此时zigw立刻出现,记录下进程的PID,假如为12345. (1) 如果在不知道程序的路径前,就 ...

  8. IO流入门-第二章-FileOutputStream

    FileOutputStreamj基本用法和方法示例 /* java.io.OutputStream java.io.FileOutputStream 文件字节输出流 将计算机内存中的数据写入到硬盘文 ...

  9. python中open函数的使用

    转自:https://www.cnblogs.com/R-ling/p/8412578.html 一.open()的函数原型open(file, mode=‘r', buffering=-1, enc ...

  10. 模块 - random/string/os/sys/shutil/zipfile/tarfile

    random 模块 方法: >>> random.randint(1,3) #会包含 1 2 3 3 >>> random.randrange(1,3) #会包含 ...