【BZOJ4709】柠檬(动态规划,单调栈)

题面

BZOJ

题解

从左取和从右取没有区别,本质上就是要分段。

设\(f[i]\)表示前\(i\)个位置的最大值。

那么相当于我们枚举一个前面的位置\(j\),然后找到这一段中最大的\(s_0t^2\)

但是这样子很不优秀。

我们贪心的思考一下,既然这一段最后加起来只能变成某一个\(s_0\),

那么,我们这一段开头和结尾都一定要是\(s_0\),

否则我们把结尾那些不等于\(s_0\)的单独分开一段,

这样子的答案一定不会更差,前缀同理。

因此每次的\(s_0\)一定由前面的某个\(s_0\)转移过来。

转移是\(f[i]=f[j-1]+s[i]t^2\),其中\(t^2\)是\([j,i]\)中\(s[i]\)的个数。

发现\(t^2\)增长很快于\(y=x\),显然这个式子是具有决策单调性的。

如果当前位置\(k\lt j\),那么一旦\(k\)的转移优于了\(j\),那么\(k\)就永远优于\(j\)了。(这不显然吗?

那么,对于每一个\(s\)都维护一个单调栈(\(vector\))

每次将后面不优的全部弹出去,然后进行转移。

注意几点:

首先是不优的靠计算,记录一下当前位置的前缀\(t\)的值,然后每次二分检查单调栈里面的第二个元素是否优于栈顶元素,也就是二分查找一下超过的时间。

还有一种可能出现的情况,即当前第二个元素不比栈顶优秀,但是第三个元素比栈顶优秀。

对于栈顶的几个元素,假设\(a<b<c\),如果\(a\)超过\(b\)的时间要早于\(b\)超过\(c\)的时间,那么\(b\)是没有意义的。

所以对于当前位置\(i\),我们检查栈顶元素和第二个元素超过\(i\)的时间

如果第二个元素超过\(i\)的时间更早,那么第一个元素就没有意义了,可以直接弹掉。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 111111
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
ll f[MAX];
vector<int> g[MAX];
int n,a[MAX],num[MAX],s[MAX];
ll calc(int j,int x){return f[j-1]+1ll*a[j]*x*x;}
int Time(int x,int y)
{
int l=1,r=n,ret=n+1;
while(l<=r)
{
int mid=(l+r)>>1;
if(calc(x,mid-s[x]+1)>=calc(y,mid-s[y]+1))ret=mid,r=mid-1;
else l=mid+1;
}
return ret;
}
int main()
{
n=read();
for(int i=1;i<=n;++i)
{
s[i]=++num[a[i]=read()];int l=g[a[i]].size();
while(l>=2&&Time(g[a[i]][l-2],g[a[i]][l-1])<=Time(g[a[i]][l-1],i))
--l,g[a[i]].pop_back();
g[a[i]].push_back(i);++l;
while(l>=2&&Time(g[a[i]][l-2],g[a[i]][l-1])<=s[i])
--l,g[a[i]].pop_back();
f[i]=calc(g[a[i]][l-1],s[i]-s[g[a[i]][l-1]]+1);
}
printf("%lld\n",f[n]);
}

【BZOJ4709】柠檬(动态规划,单调栈)的更多相关文章

  1. Luogu 1169 [ZJOI2007]棋盘制作 - 动态规划+单调栈

    Description 给一个01矩阵, 求出最大的01交错的正方形和最大的01交错的矩阵 Solution 用动态规划求出最大的正方形, 用单调栈求出最大的矩阵. 在这里仅介绍求出最大正方形(求最大 ...

  2. 【BZOJ4709】[Jsoi2011]柠檬 斜率优化+单调栈

    [BZOJ4709][Jsoi2011]柠檬 Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,0 ...

  3. BZOJ4709 Jsoi2011 柠檬【决策单调性+单调栈】

    Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们从 ...

  4. DP的各种优化(动态规划,决策单调性,斜率优化,带权二分,单调栈,单调队列)

    前缀和优化 当DP过程中需要反复从一个求和式转移的话,可以先把它预处理一下.运算一般都要满足可减性. 比较naive就不展开了. 题目 [Todo]洛谷P2513 [HAOI2009]逆序对数列 [D ...

  5. 【BZOJ 4709】柠檬 斜率优化dp+单调栈

    题意 给$n$个贝壳,可以将贝壳分成若干段,每段选取一个贝壳$s_i$,这一段$s_i$的数目为$num$,可以得到$num^2\times s_i$个柠檬,求最多能得到几个柠檬 可以发现只有在一段中 ...

  6. bzoj 4709 [Jsoi2011]柠檬——单调栈二分处理决策单调性

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4709 题解:https://blog.csdn.net/neither_nor/articl ...

  7. 【单调栈 动态规划】bzoj1057: [ZJOI2007]棋盘制作

    好像还有个名字叫做“极大化”? Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的 ...

  8. POJ 2559 Largest Rectangle in a Histogram (单调栈或者dp)

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15831 ...

  9. 洛谷P1020 导弹拦截【单调栈】

    题目:https://www.luogu.org/problemnew/show/P1020 题意: 给定一些导弹的高度. 一个导弹系统只能拦截高度不增的一系列导弹,问如果只有一个系统最多能拦截多少导 ...

随机推荐

  1. 原生与JS交互 iOS

      前言 Hybrid App(混合模式移动应用)是指介于web-app.native-app这两者之间的app,兼具“Native App良好用户交互体验的优势”和“Web App跨平台开发的优势” ...

  2. IDEA 创建Spring Boot 项目

    一.准备环境 配置Maven,打开设置页面File - Setting,快捷键Ctrl + Alt + S,找到Maven,默认是IDEA 自带的插件,User setting file 配置文件默认 ...

  3. Spring学习(2):面向接口编程思想

    一. 引言 Spring核心的IOC的实体用了面向接口编程思想,所以有必要了解下.简单来说的话,Spring就是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架. 接口的定义的概念:泛指实 ...

  4. Linux环境下Java应用性能分析定位-CPU使用篇

    1     CPU热点分析定位背景 CPU资源还是很昂贵的,为了深刻感受到这种昂贵,间下图当前CPU的资源售价: 所以对于程序猿们来说,需要让程序合理高效的使用CPU资源.利用有限的CPU资源来解决完 ...

  5. 在香港网站使用工商银行的MasterCard,工商银行所犯的低级的错误,金融安全何在

  6. 移动端rem用法总结

    先介绍一下这个近年来突起的黑马 CSS3中新增的属性,从IE9开始兼容,手机端都兼容.参考的是<html>这个标签的font-size.rem中的r就是root根的意思.所以rem要比em ...

  7. USACO 1.2.3 Name That Number 命名那个数字(打开文件)

    Description 在威斯康辛州牛大农场经营者之中,都习惯于请会计部门用连续数字给母牛打上烙印.但是,母牛用手机时并没感到这个系统的便利,它们更喜欢用它们喜欢的名字来呼叫它们的同伴,而不是用像这个 ...

  8. Win10系统自带输入法的人机交互设计

    过了寒假回校以后,我的电脑重装了系统,为了提升系统运行的速度,自己装了一个内存条同时对硬盘进行了重新的分区,对电脑内的文件也进行了重新的整理,电脑的运行速度提高了很多.老多同学都说win10系统好用, ...

  9. IHttpModule的那些事

    写在前面 关于IHttpModule的相关内容,在面试的时候也被问到过,当时也是隐隐约约的感觉这个接口有一个Init方法,可以在实现类中的Init方法注册一系列的事件,说句实话,具体哪些事件,忘了差不 ...

  10. 在pycharm中使用scrapy爬虫

    目标在Win7上建立一个Scrapy爬虫项目,以及对其进行基本操作.运行环境:电脑上已经安装了python(环境变量path已经设置好), 以及scrapy模块,IDE为Pycharm .操作如下: ...