题意:

[0,x]中全是1,判断[1,n]中的点i中是0还是1需要权值aiaia_i,最坏情况下求得到x的最小权值

n<=2000n<=2000n

Solution:

f[i][j]f[i][j]f[i][j]表示只考虑[i,j],最坏情况下求得到x的最小权值

那么f[i][j]=minjk=i(max(f[i][k−1],f[k+1][j])+a[k])f[i][j]=mink=ij(max(f[i][k−1],f[k+1][j])+a[k])f[i][j]=min_{k=i}^j(max(f[i][k-1],f[k+1][j])+a[k])

这样就得到了一个O(n3)O(n3)O(n^3)的做法

考虑优化:

发现在左端点或右端点固定的时候,f的值随着区间的长度增大而增大,说明最大值是f[i][k−1]f[i][k−1]f[i][k-1]或f[k+1][j]f[k+1][j]f[k+1][j]时,分别对应的是一段区间,那么我们可以二分分割点g,用一堆线段树维护f[i][k−1]+a[k],g⩽k⩽jf[i][k−1]+a[k],g⩽k⩽jf[i][k−1]+a[k],g⩽k⩽j 和 f[k+1][j]+a[k],i⩽k<gf[k+1][j]+a[k],i⩽k<gf[k+1][j]+a[k],i⩽k 即可

时间复杂度O(n2logn)O(n2logn)O(n^2logn) 因为要建2n棵线段树,所以空间复杂度极高,需要使用zkw线段树优化,勉强可过此题

那么还能不能继续优化呢?

我们还可以发现一个性质:对于每个状态f[i][j]f[i][j]f[i][j],它的分割点g[i][j]g[i][j]g[i][j]满足这样一个性质:g[i][j]≤g[i][j+1],g[i][j]≤g[i+1][j]g[i][j]≤g[i][j+1],g[i][j]≤g[i+1][j]g[i][j]≤g[i][j+1],g[i][j]≤g[i+1][j]

所以我们可以使用单调队列来优化转移:

我们建立n+1个单调队列,1个来维护i固定时,随着j增长所能得到的最小值

剩下的n个维护j固定时,随着i递减所能得到的最小值

这样复杂度变为O(n2)O(n2)O(n^2)

代码:

#include<cstdio>
#include<iostream>
using namespace std;
const int N=2010;
int n,a[N],q[N][N],h[N],t[N],f[N][N],g;
int main()
{scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d",&a[i]);   for (int i=n;i>=1;i--){f[i][i]=a[i],g=i;h[0]=1;t[0]=0;h[i]=t[i]=1;q[i][1]=i;for (int j=i+1;j<=n;j++){while (g<j&&f[i][g-1]<f[g+1][j]) g++;while (h[0]<=t[0]&&q[0][h[0]]<g) h[0]++;while (h[0]<=t[0]&&f[i][q[0][t[0]]-1]+a[q[0][t[0]]]>f[i][j-1]+a[j]) t[0]--;q[0][++t[0]]=j;while (h[j]<=t[j]&&q[j][h[j]]>=g) h[j]++;while (h[j]<=t[j]&&f[q[j][t[j]]+1][j]+a[q[j][t[j]]]>f[i+1][j]+a[i]) t[j]--;q[j][++t[j]]=i;f[i][j]=min(f[i][q[0][h[0]]-1]+a[q[0][h[0]]],f[q[j][h[j]]+1][j]+a[q[j][h[j]]]);}}printf("%d",f[1][n]);
}

BZOJ 2448: 挖油-区间DP+单调队列相关推荐

  1. BZOJ 2448: 挖油

    Description [0,x]中全是1,其余全是0,每个点有一个权值,求最坏情况下得到x的最小权值. Sol DP+单调队列. 首先就是一个 \(O(n^3)\) 的DP. \(f[i][j]\) ...

  2. [DP/单调队列]BZOJ 2059 [Usaco2010 Nov]Buying Feed 购买饲料

    首先我想吐槽的是题目并没有表明数据范围... 这个题目 DP方程并不难表示. dp[i][j]表示前i个地点携带了j个货物的最小花费 dp[i][j] = dp[i-1][k] + (j-k) * c ...

  3. [luogu 4292][bzoj 1758][WC2010] 重建计划(点分治 + dp + 单调队列优化 + 启发式合并)

    [WC2010]重建计划 problem solution code problem 洛谷指路 solution 一看那个道路平均价值的式子:AvgValue=∑e∈Sv(e)∣S∣\text{Avg ...

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

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

  5. bzoj2500幸福的道路 树形dp+单调队列

    2500: 幸福的道路 Time Limit: 20 Sec  Memory Limit: 256 MB Submit: 434  Solved: 170 [Submit][Status][Discu ...

  6. Codeforces 1077F2 Pictures with Kittens (hard version)(DP+单调队列优化)

    题目链接:Pictures with Kittens (hard version) 题意:给定n长度的数字序列ai,求从中选出x个满足任意k长度区间都至少有一个被选到的最大和. 题解:数据量5000, ...

  7. bzoj5185 [Usaco2018 Jan]Lifeguards(dp+单调队列优化)

    真是太神了orz 我们先贪心地把被包含的线段删掉,把剩下的线段按左端点排序,这样的话右端点显然也是有序的. 设dp[i][k],表示前i个线段,删了k个,且必须保留i线段的最大覆盖长度.枚举上一个线段 ...

  8. [NOI2005]瑰丽华尔兹(DP+单调队列优化)

    题目来源:https://www.lydsy.com/JudgeOnline/problem.php?id=1499 Description 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有 ...

  9. cactus仙人掌图【仙人掌圆方树+树形DP+单调队列】

    题目链接 BZOJ 1023 首先,圆方树是比较好想到的,维护直径,我们最方便的做法就是先让它变成一棵树,这里因为是仙人掌图,所以就用圆方树来构建. 再者,就是维护直径了,比较好想到的是非环上结点,就 ...

最新文章

  1. leetcode - 150. Evaluate Reverse Polish Notation
  2. 一个linux提权用的技巧
  3. 腾讯在信息流内容理解技术上的解决方案
  4. Semantic Element
  5. HDOJ1860 ( 统计字符 ) 【水题】
  6. 能够快速赚到钱的,一般就三类人
  7. 16 张图教你如何从 0 到 1 构建一个稳定、高性能的 Redis 集群!
  8. android shape的使用详解以及常用效果(渐变色、分割线、边框、半透明阴影效果等)...
  9. 用python写一个hello world、把代码写下来_十行代码编写一个Python小游戏,你准备好了吗?(文末赠书)...
  10. JavaSE笔记总结
  11. mysql数据库基础知识总结
  12. 历久而新,我的新书《第二行代码》已出版!
  13. pythonunicode编码_python unicode 编码整理
  14. 首届 RustCon Asia 圆满落幕——Love is electricity for RustCon Asia
  15. linux ip_conntrack_max,解?Linux NAT ip_conntrack: table full的方法
  16. 【SQL】关于SQL Server的性能优化——基础内容
  17. 2019xupt-acm校赛 题解 ( F.猜球球 ) by出题组tongtong
  18. 软件界面设计原则(转)
  19. Python下Spyder安装方法
  20. Word的样式库在 选项卡中_Word|表格的设置

热门文章

  1. Linux下svn报错:Can‘t create temporary file from template ‘/tmp/svn-XXXXXX‘: Permission denied
  2. 华为云城市峰会深圳站 · 华为云区块链助力金融创新
  3. Centos7.4在vmware6.5下基于nfs和dd实现虚机的备份恢复
  4. pokers -end
  5. python怎么画人像_教你如何用Python画出心目中的自己
  6. Windows Embedded CE和Windows Mobile下ActiveSync开发
  7. ubuntu 12.04 ATI 驱动
  8. 【军事】“运筹帷幄”的利器:二三维一体化实战指挥辅助决策系统
  9. 二进制枚举子集(总结+应用)
  10. java set子集_Java程序来检查一个集合是否是另一个集合的子集