[BZOJ]4709 柠檬 DP单调性优化 + 单调栈

BZOJ4709 浅谈单调栈 世界真的很大 单调栈这东西其实挺玄学的。。 看起来很好懂其实应用还是很广的,认真想起来还是很烧脑。 以题为例 descriptionFlute 很喜欢柠檬。它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬。贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上。为了方便,我们从左到右给贝壳编号 1..N。每只贝壳的大小不一定相同, 贝壳 i 的大小为 si(1 阅读详情

4709: [Jsoi2011]柠檬

Time Limit: 10 Sec   Memory Limit: 128 MB
Submit: 252   Solved: 111
[ Submit][ Status][ Discuss]

Description

Flute 很喜欢柠檬。它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬。贝壳一共有 N (1 ≤ N
 ≤ 100,000) 只,按顺序串在树枝上。为了方便,我们从左到右给贝壳编号 1..N。每只贝壳的大小不一定相同,
贝壳 i 的大小为 si(1 ≤ si ≤10,000)。变柠檬的魔法要求,Flute 每次从树枝一端取下一小段连续的贝壳,并
选择一种贝壳的大小 s0。如果 这一小段贝壳中 大小为 s0 的贝壳有 t 只,那么魔法可以把这一小段贝壳变成 s
0t^2 只柠檬。Flute 可以取任意多次贝壳,直到树枝上的贝壳被全部取完。各个小段中,Flute 选择的贝壳大小 s
0 可以不同。而最终 Flute 得到的柠檬数,就是所有小段柠檬数的总和。Flute 想知道,它最多能用这一串贝壳
变出多少柠檬。请你帮忙解决这个问题。

Input

第 1 行:一个整数,表示 N。
第 2 .. N + 1 行:每行一个整数,第 i + 1 行表示 si。

Output

仅一个整数,表示 Flute 最多能得到的柠檬数。

Sample Input

5
2
2
5
2
3

Sample Output

21
//Flute 先从左端取下 4 只贝壳,它们的大小为 2, 2, 5, 2。选择 s0 = 2,那么这一段
里有 3 只大小为 s0 的贝壳,通过魔法可以得到 2×3^2 = 18 只柠檬。再从右端取下最后一
只贝壳,通过魔法可以得到 1×3^1 = 3 只柠檬。总共可以得到 18 + 3 = 21 只柠檬。没有
比这更优的方案了。

HINT

Source

[ Submit][ Status][ Discuss]


HOME Back

  

  这道题有点好玩...网上很少的人写题解, 今天看了neither_nor的题解之后对于某个地方还是很困惑,不过多多证明后还是豁然开朗. 下面写一下自己的理解.

  先附上neither_nor的题解.

  考虑DP,f[i]表示前i个的最大价值.

  那么在最后一段所选的颜色一定是i的情况下,最后一段的开头的颜色也一定是i的颜色,否则开头一段也没有贡献,不然单分出去一段.

  我们发现对于任意一个i,他所选的最后一段所指定的颜色一定是i的颜色,因为否则的话i这个点就会没有贡献,一定不如最后一段只选一个i.

  那么对于f[i],假设之前存在一个点j,这个点的颜色a[j]与i的颜色a[i]相等,那么我们可以让f[i]由j转移,价值为f[j-1]+a[j]*(s[i]-s[j]+1)^2,s[i]代表前i个数里a[i]出现的次数

  我们发现对于任意一个颜色x,随着这个颜色的数不断出现,由每一个之前的a[j]=x的j转移所产生的价值都会不断增加,且j越小,增加的越块,如果有j1<j2,并且j1当前的价值比j2大了,那么j2就没有用了,于是我们可以维护一个单调栈,每次如果栈顶第二个的元素超过了栈顶,就把栈顶弹出,决策的时候直接用栈顶决策

  而我们发现可能会出现栈顶第三个元素超过了栈顶,而栈顶第二个元素还没超过栈顶的情况,我们需要避免这种情况。我们发现对于任意的j1<j2<i1<i2,如果j1超过i1的时间比j2超过i1的时间要早,那么j1超过i2的时间也一定比j2超过i2的时间早,证明显然,并且我们对于任意的(j1,j2),j1<j2,我们都能直接算出在第几个颜色与j1,j2相等的数出现的时候,j1会超过j2,那么在我们即将把i压入栈顶的时候,只要当前栈顶第二个元素超过i的时间比当前栈顶超过i的时间要早,那么栈顶就也没用了,我们就可以弹栈,这样的话栈里的每一个元素超过上一个元素的时间也是单调的,于是就没有问题了.

  我对最后一段的理解是:

  因为我们要避免每一个元素超过上一个元素的时间也是单调的, 那么设栈里第二个元素为j2, 栈顶即第一个元素为j1, 即将加入栈的为i, 那么当j2超过j1的时候比j1超过i的时候早,那么我们弹栈. 先考虑为什么这么做, 首先这样能弹栈说明了j1一定不优. 证明: 由于本身i这个地方可以自成一段,也就是说i是可以用i点这个决策的, 那么当j1比i优的时候, j1不应该弹栈,否则肯定弹栈.

  但又因为j1如果比i优的话, 当j1比i优的时候, j2已经比j1优了(这是弹栈条件), 所以j1还是要被弹栈. 所以满足这个条件弹栈肯定是没有问题的. 接下来我们再看为什么这样就能保证每一个元素超过上一个元素的时间也是单调的,因为我们通过弹栈保证了, j2比j1优的时间一定 比 j1比i优的时间晚(否则j1就被弹出去了), 那么因为我们一直这样保证, 所以当i已经不再是栈顶元素是, 因为j2比j1优的时间一定比j1比i优的时间晚, 那么设压在i之上的元素是p, 我们也保证了j1比i优的时间晚肯定比 i比p优的时间晚(否则我们要弹栈, 现在讨论的是一个合法的即真正单调的单调栈). 这样递推下去,栈中一层比一层晚, 所以就不会出现栈顶第三个元素超过了栈顶,而栈顶第二个元素还没超过栈顶的情况.

#include<stdio.h>
#include<vector>
using namespace std;
typedef long long dnt;
const int maxn = 100005;
int n;
dnt f[maxn];
vector<int> g[10005];
int s[maxn], a[maxn], cnt[10005];
inline dnt calc(int x, int y){
	return f[x - 1] + (dnt) a[x] * y * y;
}
inline int find(int x, int y){
	int lf = 1, rg = n;
	int ans = n + 1;
	while(lf <= rg){
		int mid = (lf + rg) >> 1;
		if(calc(x, mid - s[x] + 1) >= calc(y, mid - s[y] + 1)) ans = mid, rg = mid - 1;
		else lf = mid + 1;
	}
	return ans;
}
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		int x;
		scanf("%d", &x);
		a[i] = x, s[i] = ++cnt[x];
		while(g[x].size() >= 2 && find(g[x][g[x].size() - 2], g[x][g[x].size() - 1])
							   <= find(g[x][g[x].size() - 1], i)) g[x].pop_back();
		g[x].push_back(i);
		while(g[x].size() >= 2 && find(g[x][g[x].size() - 2], g[x][g[x].size() - 1]) <= s[i])
							   g[x].pop_back();
		f[i] = calc(g[x][g[x].size() - 1], s[i] - s[g[x][g[x].size() - 1]] + 1);
	}
	printf("%lld\n", f[n]);
}


LeGo-LOAM源码篇:源码分析(3) mapOptmization.cpp,主要内容包括回环检测、scan-to-map位姿优化、因子图。 阅读详情

相关推荐

保姆级教程:手把手带你复现APFNet论文的RGBT目标跟踪模型(附完整代码与数据集配置)

本文提供了一份详细的APFNet论文复现指南,涵盖从环境搭建到模型测试的全流程。通过解析多模态融合模块和渐进式训练流程,帮助读者高效完成RGBT目标跟踪模型的复现工作,特别针对训练和测试中的常见问题提供实用解决方案。

weixin_29056781的博客 341

bzoj 3401 && bzoj 1657 单调栈

题意:对于每一个i,找到离它最近的j满足 i 倒序单调栈 type rec=record h,num:longint; end; var n,top :longint; i :longint; a,ans :array[0..100010

Eirlys的博客 430

Codesys电子凸轮Cam表实战:从可视化配置到程序化构建

本文详细介绍了Codesys电子凸轮Cam表的实战应用,从可视化配置到程序化构建的全过程。通过包装机和印刷机案例,解析Cam表的基础设置、调试技巧及动态构建方法,帮助工程师快速掌握电子凸轮技术,提升运动控制精度和效率。

weixin_29309785的博客 297

BZOJ 2086--[Poi2010]Blocks【单调栈】

Description给出N个正整数a[1..N],再给出一个正整数k,现在可以进行如下操作:每次选择一个大于k的正整数a[i],将a[i]减去1,选择a[i-1]或a[i+1]中的一个加上1。经过一定次数的操作后,问最大能够选出多长的一个连续子序列,使得这个子序列的每个数都不小于k。 总共给出M次询问,每次询问给出的k不同,你需要分别回答。题解首先,题目的什么操作都是假的,将一个数加一,一个数减

Sdywolf的博客 533

Score Matching(得分匹配)

Score Matching(得分匹配)是一种统计学习方法,用于估计概率密度函数的梯度(即得分函数),而无需知道密度函数的归一化常数。这种方法由Hyvärinen在2005年提出,主要用于无监督学习,特别是在密度估计和生成模型中。

weixin_39699362的博客 2167

gem5 prefetcher

最近在gem5上做预取实验,添加自己的预取算法,这里采用hardware stream prefetcher , 修改了几个bug才给实验调试通过,发文记录下实验过程。 gem5上添加自己的预取算法步骤: (1)路径gem5-master/configs/common/Caches.py下,开启预取:class L1Cache(Cache): assoc = 2 tag_late

编程邦 3843

【学习笔记】各类基于决策单调性的dp优化

个人认为已经非常非常全了,从入门到入土的知识点都在里面了,以及本人踩过的所有坑的(泪目

sophilex的博客 1989

PostgreSQL高可用之主备复制

多个PostgreSQL可协同工作,如果主库发生宕机备库将迅速进行接管并对外提供服务以实现高可用。本文将从主备复制、主备切换、故障转移等角度进行实际测试演练。第一章主备复制是基础,通过主备复制可以得到一个或多个相同的实例。在主备复制的基础上通过第二章主备切换介绍了如何手工将主库与备库互换角色。在第三章中,采用了Keepalived进行实时监测,在主库宕机后,使用主备切换中提到的命令使备库升级为主库并对外提供服务,以达到PostgreSQL高可用的目标。

asdasdsaff的博客 1347

【学习笔记】决策单调性优化DP

GDCPC还在发力,清华出题组出的牛客还是 4 题。这次没有min25筛,不然我能5题(bushi除了一道用 prufer 序列的恶心 DP 外,还有一道DP题是一个状态难想,并且还需要决策单调性优化的DP,被认为是偏简单的银牌题。

Brute♂force 1337

【数字IC基础】DFT(Design For Test)可测性设计

【数字IC基础】DFT(Design For Test)可测性设计

努力,加油每一天鸭~ 3463

IPD流程中的RR\OR\IR\PB\SR\AR\CR等名词汇总(基于新的产品包需求架构)

RR:Raw Requirement,原始需求=》IR:Initial Requirement,初始需求=》SR:System Requirement,系统需求=》AR:Allocated Requirement,分配需求=》CR:Process Change Requirement,流程变更需求。

a1809032425的博客 3186

BZOJ_P3100 排列(单调栈)

BZOJ传送门Time Limit: 10 Sec Memory Limit: 16 MB Submit: 430 Solved: 120 [Submit][Status][Discuss] Description 给定一个长度为n的序列a,选取连续的一段使其为1~k的一个排列。 求k的最大值。Input 输入的第一行包含一个整数n。接下来n个数描述序列aOutput 输出一个整

BeiYu 577

SpringCloud Alibaba - Seata 实现高可用和异地容灾

这里不仅仅要实现高可用,还需要实现异地容灾. 异地容灾就是说,如果你整了好几个节点部署起来,全部放到一个机房里面,那么如果这个机房出了故障,就意味着整个集群就完了,所以对于一个大型的集群来讲,都会把这些服务异地部署.问题2:如果我们要实现异地容灾,也就说某一个机房挂了,需要快速的切换到另一个可用的机房,但是这个配置在配置文件中写死了,如果要改配置文件,还需要重启服务器,这是我们不希望看到的,怎么办?进入 seata/bin 目录,运行 seata-server.bat 文件,默认端口为 8091。

CYK_byte的博客 973

【BZOJ4709】柠檬(JSOI2011)-决策单调性优化DP+单调栈

测试地址:柠檬 做法:本题需要用到决策单调性优化DP+单调栈。 首先需要发现一个结论:最优方案中被分成的每一段的头尾贝壳的大小应该是相同的,并且这一段中产生贡献的就是这个大小。因为如果上面条件中有一个不满足,我们把某个端点单独分成一个段就比这个方案更优了。于是我们令f(i)f(i)f(i)为前iii个贝壳能得到的最大答案,有以下状态转移方程: f(i)=max{f(j−1)+sj(sum(i...

Maxwei_wzj的OI世界 648

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【BZOJ4709】柠檬(决策单调性)

题目链接 题目描述 Flute 很喜欢柠檬。它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬。贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上。为了方便,我们从左到右给贝壳编号 1..N。每只贝壳的大小不一定相同, 贝壳 i 的大小为 si(1 ≤ si ≤10,000)。变柠檬的魔法要求,Flute 每次从树枝一端取下一小段连续的贝壳,并 选择...

Yu Gi Oh! 706

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

bzoj4709 柠檬 单调栈,DP,斜率优化

目录 思路 错误 代码 /* 思路 s是值等于a[i]的前缀和 转移方程$f[i]=max(f[i],f[j-1]+a[i]*(s[i]-s[j]+1)*(s[i]-s[j]+1))$ 不难写出暴力方程(by wxyww) //@baoli memset(f,-0x3f,s...

weixin_30352191的博客 130

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

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

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4709 题解:https://blog.youkuaiyun.com/neither_nor/article/details/53285115 每次选的段的两端种类相同。因为贡献有个数的二次方,所以对于 i ,更小的 j 的 [ j+1 , i ] 之间部分的贡献增长得更快。所以随着个数的增加,较小的...

weixin_34233856的博客 169

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

前缀和优化 当DP过程中需要反复从一个求和式转移的话,可以先把它预处理一下。运算一般都要满足可减性。 比较naive就不展开了。 题目 【Todo】洛谷P2513 [HAOI2009]逆序对数列 【Done】洛谷P2511 [HAOI2008]木棍分割 【Done】洛谷P4099 [HEOI2013]SAO 【Done】NOIAC37 染色 单调队列优化 前置技能:单调队列(经典的问题模...

a83229442的博客 638

BZOJ 4709 柠檬

注意到一个最优区间的 s0==区间的开头 && s0==区间的结尾,那么我们有个N^2的dp。 f[i]=max(f[j-1]+a[i]*(s[i]-s[j]+1)^2)。 注意到单调性,在栈上二分答案。 #include<bits/stdc++.h> #define Max(a,b) (a>b?a:b) using namesp...

133

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

题意 给$n$个贝壳,可以将贝壳分成若干段,每段选取一个贝壳$s_i$,这一段$s_i$的数目为$num$,可以得到$num^2\times s_i$个柠檬,求最多能得到几个柠檬 可以发现只有在一段中首尾颜色相同的情况下最优,所以每次选取一段里末位的$s_i$变成柠檬,于是有$f_i=max_{j \le i}{f_{j-1}+s_i\times(pre_i-pre_j+1)^2}$ ,$pre...

weixin_30872789的博客 167

[BZOJ4709][JSOI2011]柠檬 决策单调性优化dp

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4709 我好弱啊QAQ,网上dalao们的题解根本看不懂啊,折腾了几个小时,有一点明白了。 首先要把朴素dp方程退出来。 ①题目中说每次从序列的左右选一端取,但是如果你真的照着题目说的这样做我也不知道会怎么样。事实上很明显不管怎么取,最终答案都只跟划分出的是哪几个区间有关。...

weixin_30556161的博客 96

【bzoj4709】[Jsoi2011]柠檬 决策单调性+dp

Description Flute 很喜欢柠檬。它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬。贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上。为了方便,我们从左到右给贝壳编号 1..N。每只贝壳的大小不一定相同, 贝壳 i 的大小为 si(1 ≤ si ≤10,000)。变柠檬的魔法要求,Flute 每次从树枝一端取下一小段连续的贝壳,并 选择一种贝壳的大...

weixin_30822451的博客 149

bzoj4709柠檬

一开始写了个O(n2)O(n^2)的暴力DP,找了波规律,发现每种数字的最优转移点一定是同种数字(话说这对于强的人来说可能不必找规律吧,看来我还是太菜了) 然后的想法就是平方函数具有下凸性,可以决策单调性优化,每次维护一个单调栈,再暴力弹栈就行了。 写完后发现跟暴力拍不上,单步了一会发现一种情况是第3个元素优于第1个元素优于第2个元素,然后暴力弹栈就挂了。 百度了题解,知道了可以预计算每个元素

zx2003的博客 414

bzoj 4709: [Jsoi2011]柠檬

Description Flute 很喜欢柠檬。它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬。贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上。为了方便,我们从左到右给贝壳编号 1..N。每只贝壳的大小不一定相同, 贝壳 i 的大小为 si(1 ≤ si ≤10,000)。变柠檬的魔法要求,Flute 每次从树枝一端取下一小段连续的贝壳,并 选择一种贝壳的大...

weixin_30686845的博客 125

[BZOJ4709][JSOI2011]柠檬[决策单调性优化]

有太多题解在瞎写,发这个主要是提醒一下不要被傻逼们写的东西误导 好几次想要把这个题想明白,但那些所谓的“题解”让我浪费了许多天时间 二分的是s[i],单调栈里的元素比较关键字也是s[i],而不是位置,要是强行把s[i]说成时间,我仏了 随便看看其他人写的,不管正确性,不管是否理解,把代码和文字抄过去,就会产生这种“题解”,网络垃圾 问某人,说“不懂啊,照其他题解抄的”,你就继续制造一篇垃圾题解...

weixin_34384681的博客 126

bzoj4709 [Jsoi2011]柠檬(贪心+dp+决策单调性+单调栈)

问题就是把这个序列分成若干段,使得每段的贡献和最大。 首先我们贪心地发现每段的起终位置一定相同(否则分出去更好) 于是有dp,f[i]表示前i个的最大贡献。枚举i这一段的起点j,一定满足a[i]==a[j],记c[i]表示i及i之前出现了多少个a[i] f[i]=maxj=1i{f[j−1]+a[i]∗(c[i]−c[j]+1)2|a[j]==a[i]}f[i]=maxj=1i{f[j−1]...

Icefox的博客 435
上一篇: [BZOJ]3140 二分图最大匹配
下一篇: 二分图的最小顶点覆盖 和 最大独立集 和 最大团
MaxMercer
博客等级 码龄10年 55粉丝 261原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值