第一种方法是决策单调性优化DP。

决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优。

根号函数是一个典型的具有决策单调性的函数,由于根号函数斜率递减,所以i决策的贡献的增长速度必定比j快。

于是使用基础的决策单调性优化即可。

注意两个问题,一是DP函数要存实数而不能存整数,因为先取整会丢失在后面的判断中需要的信息。二是记录决策作用区间的时候左端点要实时更新,即下面的p[st].l++,否则在二分时会出现错误。

  1. #include<cmath>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #define rep(i,l,r) for (int i=(l); i<=(r); i++)
  5. using namespace std;
  6.  
  7. const int N=;
  8. double f[N],g[N];
  9. int n,st,ed,h[N];
  10. struct P{ int l,r,p; }q[N];
  11.  
  12. int Abs(int x){ return (x>) ? x : -x; }
  13. double cal(int x,int y){ return h[x]-h[y]+sqrt(Abs(y-x)); }
  14.  
  15. int find(P a,int b){
  16. int L=a.l,R=a.r;
  17. while (L<R){
  18. int mid=(L+R)>>;
  19. if (cal(a.p,mid)>=cal(b,mid)) L=mid+; else R=mid;
  20. }
  21. return L;
  22. }
  23.  
  24. void work(double f[]){
  25. st=ed=; q[]=(P){,n,};
  26. rep(i,,n){
  27. q[st].l++; if (q[st].l>q[st].r) st++;
  28. f[i]=cal(q[st].p,i);
  29. if (st>ed || (cal(q[ed].p,n)<cal(i,n))){
  30. while (st<=ed && cal(q[ed].p,q[ed].l)<cal(i,q[ed].l)) ed--;
  31. if (st>ed) q[++ed]=(P){i,n,i};
  32. else{
  33. int t=find(q[ed],i); q[ed].r=t-; q[++ed]=(P){t,n,i};
  34. }
  35. }
  36. }
  37. }
  38.  
  39. int main(){
  40. scanf("%d",&n);
  41. rep(i,,n) scanf("%d",&h[i]);
  42. work(f); reverse(h+,h+n+);
  43. work(g); reverse(g+,g+n+);
  44. rep(i,,n) printf("%d\n",max((int)ceil(max(f[i],g[i])),));
  45. return ;
  46. }

第二种方法是分块。

这题中,对于固定的i,sqrt(i-j)只有O(sqrt(n))种取值,而每种取值的区间长度也只有O(sqrt(n))个。

预处理从每个数开始后O(sqrt(n))个数中的最大值,暴力枚举sqrt(i-j)的取值更新答案。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #define rep(i,l,r) for (int i=(l); i<=(r); i++)
  6. typedef long long ll;
  7. using namespace std;
  8.  
  9. const int N=,K=;
  10. int n,ans,h[N],mx[N][];
  11.  
  12. int main(){
  13. freopen("bzoj4850.in","r",stdin);
  14. freopen("bzoj4850.out","w",stdout);
  15. scanf("%d",&n);
  16. rep(i,,n) scanf("%d",&h[i]);
  17. rep(i,,n){
  18. mx[i][]=h[i];
  19. rep(j,,min(K,n-i+)) mx[i][j]=max(mx[i][j-],h[i+j-]);
  20. }
  21. rep(i,,n){
  22. ans=;
  23. for (int pos=i,j=,nxt; pos!=; j++)
  24. nxt=pos-,pos=max(pos-j*+,),ans=max(ans,mx[pos][nxt-pos+]-h[i]+j);
  25. for (int pos,j=,nxt=i; nxt!=n; j++)
  26. pos=nxt+,nxt=min(nxt+j*-,n),ans=max(ans,mx[pos][nxt-pos+]-h[i]+j);
  27. printf("%d\n",ans);
  28. }
  29. return ;
  30. }

[BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)的更多相关文章

  1. Lightning Conductor 洛谷P3515 决策单调性优化DP

    遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...

  2. CF868F Yet Another Minimization Problem 分治决策单调性优化DP

    题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...

  3. 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)

    传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...

  4. BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】

    Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt( ...

  5. 决策单调性优化dp 专题练习

    决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...

  6. 洛谷 P5897 - [IOI2013]wombats(决策单调性优化 dp+线段树分块)

    题面传送门 首先注意到这次行数与列数不同阶,列数只有 \(200\),而行数高达 \(5000\),因此可以考虑以行为下标建线段树,线段树上每个区间 \([l,r]\) 开一个 \(200\times ...

  7. BZOJ4899: 记忆的轮廓【概率期望DP】【决策单调性优化DP】

    Description 通往贤者之塔的路上,有许多的危机. 我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增, 在[1,n]中,一共有n个节点.我 ...

  8. 2018.10.14 NOIP训练 猜数游戏(决策单调性优化dp)

    传送门 一道神奇的dp题. 这题的决策单调性优化跟普通的不同. 首先发现这道题只跟r−lr-lr−l有关. 然后定义状态f[i][j]f[i][j]f[i][j]表示猜范围为[L,L+i−1][L,L ...

  9. 算法学习——决策单调性优化DP

    update in 2019.1.21 优化了一下文中年代久远的代码 的格式…… 什么是决策单调性? 在满足决策单调性的情况下,通常决策点会形如1111112222224444445555588888 ...

随机推荐

  1. prim算法记录路径

    题目链接:https://vjudge.net/contest/66965#problem/H 代码: #include<iostream> #include<string> ...

  2. Android平台介绍

    一.Android平台介绍 什么是智能手机 具有独立的操作系统,独立的运行空间,可以由用户自行安装软件.游戏.导航等第三方应用程序,并可以通过移动通讯网络来实现无线网络接入的手机类型总称. 智能手机操 ...

  3. 使用qt写的进制转换器

    没有使用什么数据结构,直接使用qt自带的进制转换函数, 实时出结果,代码在后面的链接中,由于初学qt,好多不会,代码构造就有点乱 截图如下

  4. 【codeforces】【比赛题解】#864 CF Round #436 (Div.2)

    做出了4题,还不错,可惜还是掉rating……能保持在蓝名已经不错了. 题目跳转链接. [A]公平的游戏 题意: Petya和Vasya在玩游戏.他们有n张卡片(n是偶数).每张卡片上有一个整数. 游 ...

  5. 【不知道是啥的NOIP模拟赛】网络入侵

    题意是这样的: 给你一棵树,每个边有一个初始的0/1边权.你希望把它弄成一个给定的样子. 你每次可以选一条树链取反,然后问你最少要操作几次. ----------------------------- ...

  6. 1->小规模集群架构规划

    "配置无人值守批量安装系统(Cobbler)" "搭建PPTP VPN/ NTP/Firewalld内部共享上网 " "搭建跳板机服务jumpserv ...

  7. poj1976

    dp #include <cstdio> #include <cstring> #include <algorithm> using namespace std; ...

  8. 01 Getting Started 开始

    Getting Started 开始 Install the Go tools Test your installation Uninstalling Go Getting help   Downlo ...

  9. Filter过滤器-JavaWeb三大组件之一

    Servlet.Filter.Listener是JavaWeb的三大组件,给Web开发提供了很大的便利. 什么是Filter? Filter,过滤器.类似与生活中的净水器.空气净化器. JavaWeb ...

  10. lambda表达式与bind函数

    #include<iostream> #include<algorithm> #include<sstream> #include<vector> #i ...