题解 [JSOI2011]柠檬
题目大意
给出一个区间,每个点都有一个颜色,把这个区间分为许多块,每一块的权值为 \(\max\{s\times t^2\}\) ,其中 \(s\) 为某种颜色,\(t\) 为该颜色在该块中出现的次数。问最大权值之和。
\(n\le 10^5,s_i\le 10^4\)
思路
话说用笔记本打代码真的好难受啊!!!
首先我们可以看出这个肯定是个 dp ,可以列出 dp 式:
\]
于是问题就是如何求出 \(\text{count}(j\to i)\)。
我们经过思(mang)考(cai)发现,其实在最优情况下,每一段的两端的颜色一定是相同的,而且产生贡献的颜色也一定是两端的颜色。
至于证明的话可以感性理解一下就是说,如果不同的话可以把一段分到另外一边,这样不会让答案变劣。
然后,我们发现这下就可以做了。我们可以设 \(p_{i,j}\) 表示颜色 \(i\) 第 \(j\) 个出现的数的位置,那我们就可以得到转移式:
\]
然后你发现这个东西就可以斜率优化了,最后的式子就是:
\]
的时候,\(b\) 比 \(a\) 更优。
然后你发现这个东西就是一个上凸壳,然后你每次弹得时候就是把队尾弹出来(因为上凸壳斜率递减,对于相同的 \(i\),它的 \(2i(j+1)\) 单调递增)。
于是时间复杂度就是 \(\Theta(n)\) 。
\(\texttt{Code}\)
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define int long long
#define MAXN 100005
template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
vector <int> stk[MAXN];
int top1 (vector <int> &vec){return vec[vec.size() - 1];}
int top2 (vector <int> &vec){return vec[vec.size() - 2];}
int n,s[MAXN],c[MAXN],f[MAXN],tot[MAXN];
int Y (int i){return f[i - 1] + c[i] * c[i] * s[i];}
int X (int i){return c[i];}
int calc (int x,int y){return f[y - 1] + s[x] * (c[x] - c[y] + 1) * (c[x] - c[y] + 1);}
double Slope (int x,int y){return (Y(y) - Y(x)) * 1.0 / (X(y) - X(x));}
signed main(){
read (n);
for (Int i = 1;i <= n;++ i) read (s[i]),c[i] = ++ tot[s[i]];
for (Int i = 1;i <= n;++ i){
int col = s[i],ind = c[i] + 1;
while (stk[col].size() >= 2 && Slope (top2(stk[col]),top1(stk[col])) <= Slope (top1(stk[col]),i)) stk[col].pop_back ();
stk[col].push_back (i);
while (stk[col].size() >= 2 && Slope(top2(stk[col]),top1(stk[col])) <= 2 * s[i] * (c[i] + 1)) stk[col].pop_back ();
f[i] = calc (i,top1(stk[col]));
}
write (f[n]),putchar ('\n');
return 0;
}
题解 [JSOI2011]柠檬的更多相关文章
- bzoj4709: [Jsoi2011]柠檬 斜率优化
题目链接 bzoj4709: [Jsoi2011]柠檬 题解 斜率优化 设 \(f[i]\) 表示前 \(i\)个数分成若干段的最大总价值. 对于分成的每一段,左端点的数.右端点的数.选择的数一定是相 ...
- 【BZOJ4709】[Jsoi2011]柠檬 斜率优化+单调栈
[BZOJ4709][Jsoi2011]柠檬 Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,0 ...
- 【LG5504】[JSOI2011]柠檬
[LG5504][JSOI2011]柠檬 题面 洛谷 题解 考虑\(dp\),令\(f_i\)表示\(dp\)到第\(i\)位且在第\(i\)位分段的最大值. 我们令题面中的\(s_i\)为\(a_i ...
- 4709: [Jsoi2011]柠檬
4709: [Jsoi2011]柠檬 https://www.lydsy.com/JudgeOnline/problem.php?id=4709 分析: 决策单调性+栈+二分. 首先挖掘性质:每个段选 ...
- 【BZOJ】4709: [Jsoi2011]柠檬
4709: [Jsoi2011]柠檬 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 779 Solved: 310[Submit][Status][ ...
- 笔记-[JSOI2011]柠檬
笔记-[JSOI2011]柠檬 [JSOI2011]柠檬 \(f_i\) 表示到第 \(i\) 只贝壳最多可以换得的柠檬数. 令 \(c_i=\sum_{h=1}^i[s_h=s_i]\). \[\b ...
- 【bzoj4709】[Jsoi2011]柠檬 斜率优化
题目描述 给你一个长度为 $n$ 的序列,将其分成若干段,每段选择一个数,获得 $这个数\times 它在这段出现次数的平方$ 的价值.求最大总价值. $n\le 10^5$ . 输入 第 1 行:一 ...
- bzoj4709 [jsoi2011]柠檬
Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们 ...
- [BZOJ4709][JSOI2011]柠檬 决策单调性优化dp
题解: 解法1: 单调栈优化 首先发现一个性质就是 如果当前从i转移比从j转移更加优秀 那么之后就不会从j转移 所以我们考虑利用这个性质 我们要维护一个队列保证前一个超过后一个的时间单调不减 怎么来维 ...
随机推荐
- pgsql学习
--求所有人的薪水的总和,平均值,最大值,最小值 select sum(sal) , avg(sal), max(sal) , min(sal) from emp; --求总的行数 select co ...
- 小程序跨页面传递data数据的三种方法
Q:小程序怎么把页面data里的数据传到另外的页面? 或者小程序怎么吧表单里的数据传到另外的页面?A:1.可以使用url传递数据. 例如在A页面中传递数据,需要注意的是,wx.switchTab中的u ...
- linux系统下查看svn服务是否启动,重启及设置开机重启
Linux系统中svn服务是否启动,重启及设置开机启动 安装完svn服务器后虽然好用但是因为经常重启Linux服务器,每次重启完就要去手动启动svn服务器,很是麻烦,于是在网上找了一些方法后,自己 ...
- 学习Linux tar 命令:最简单也最困难
摘要:在本文中,您将学习与tar 命令一起使用的最常用标志.如何创建和提取 tar 存档以及如何创建和提取 gzip 压缩的 tar 存档. 本文分享自华为云社区<Linux 中的 Tar 命令 ...
- spring boot 系列之八:SpringBoot处理定时任务
项目经常会用到定时任务,springboot自然是可以通过整合相关组件来实现的. 目前常用的定时任务的实现有两种: 通过spring 自带的定时器任务@Schedule来实现 通过Quartz来实现 ...
- 二、grep文本搜索工具
grep命令作为Unix中用于文本搜索的神奇工具,能够接受正则表达式,生成各种格式的输出.除此外,它还有大量有趣的选项. # 搜索包含特定模式的文本行: [root@centos8 ~]#grep p ...
- Intel® QAT加速卡之同步异步模式
QAT 的两种操作模式 Intel QAT API同时支持同步和异步两种操作模式. 为了获得最佳性能,该应用程序应能够向加速引擎提交多个未完成的请求. 提交多个未完成的请求可最大程度地减少加速引擎上的 ...
- 解决CSDN文章下载后,依然请求跳转至首页出错的问题
1. 搜索关键字:"onerror" 然后找到如下所示代码: <div style="display:none;"> <img ...
- python3 spider [ urllib.request ]
# # 导入urllib库的urlopen函数 # from urllib.request import urlopen # # 发出请求,获取html # html = urlopen(" ...
- 基于Ubuntu18.04一站式部署(python-mysql-redis-nginx)
基于Ubuntu18.04一站式部署 Python3.6.8的安装 1. 安装依赖 ~$ sudo apt install openssl* zlib* 2. 安装python3.6.8(个人建议从官 ...