4709: [Jsoi2011]柠檬

Time Limit: 10 Sec  Memory Limit: 128 MB

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
HINT:Flute 先从左端取下 4 只贝壳,它们的大小为 2, 2, 5, 2。选择 s0 = 2,那么这一段
里有 3 只大小为 s0 的贝壳,通过魔法可以得到 2×3^2 = 18 只柠檬。再从右端取下最后一
只贝壳,通过魔法可以得到 1×3^1 = 3 只柠檬。总共可以得到 18 + 3 = 21 只柠檬。没有
比这更优的方案了。
 
题解
膜一波ZYFdalao
首先我们需要分析出一个性质:同一段被取下的贝壳,其第一个和最后一个的大小一定是一样的.
证明很容易.用反证法来看,如果有一段贝壳,开头和结尾不一样,显然把这两段分开施法更优
这样,我们又可以想出一个暴力:每一个节点的最大价值f[i],肯定是由前面某一个和他权值相同的点转移而来
设出现次数为s[i],权值为a[i]
显然我们可以写出暴力式子:f[i]=max{f[j-1]+a[i]*(s[i]-s[j]+1)2,a[i]==a[j]}
但是这样肯定会T的,所以我们考虑优化
对于两个决策点j1和j2,设j1<j2
如果一开始f[j1-1]+a[i]*(s[i]-s[j1]+1)2<f[j2-1]+a[i]*(s[i]-s[j2]+1)2
随着i不断向后,由于平方的增速很快,越靠前的j位置,越有可能反超,使得f[j1-1]+a[i']*(s[i']-s[j1]+1)2>f[j2-1]+a[i']*(s[i']-s[j2]+1)2
所以我们就不能再用单调队列了,因为如果我们删去了前面的某个点,它在后面可能会变得更优
于是我们考虑用单调栈维护这个东西(单调栈的实现方法随意,我个人使用了vector)
每次决策的时候,我们就用栈顶来更新
由于一个贝壳可以自己画为一段,所以应该在插入之后再计算f值
当上述"反超"的情况出现时,肯定是最先发生在栈顶和栈顶第二个元素
假设我们已经插入因此我们就看,第二个元素有"多快"超过栈顶
这个所谓的"速度"用经过a[i]的个数来体现,也就是说,看第二个元素经过几个a[i]超过栈顶,记为cnt1,如果cnt1<=s[i],我们就可以弹栈了.
但是,可能会出现一种情况:第三个元素超过栈顶,而第二个元素还没有超过栈顶
设j2<j1<i2<i1,如果j2,j1,i2三者满足这种情况,那么j2,j1,i1肯定更加满足这种情况,所以直接删掉j1就行
所以,在我们插入之前,可以先进行一波上述弹栈:如果发现第二个元素超过栈顶比栈顶超过i快,就弹栈;
所以最后的顺序是:排查->插入->计算
代码见下:
 #include<cstdio>
#include<cstring>
#include<vector>
#include<deque>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=;
const int V=;
LL a[N],f[N];
int id[N],cnt[V],n;
vector<int>q[V];
inline int max(int a,int b){return a>b?a:b;}
inline LL calc(int x,int y){return f[x-]+a[x]*y*y;}
inline int k(int x,int y)
{
int le=,ri=n,ret=n+;
while(le<=ri)
{
int mi=(le+ri)>>;
if(calc(x,mi-id[x]+)>=calc(y,mi-id[y]+))
ret=mi,ri=mi-;
else le=mi+;
}
return ret;
}
int main()
{
scanf("%d",&n);int o;
for(int i=;i<=n;i++)
{
scanf("%lld",&a[i]);o=a[i];
cnt[o]++,id[i]=cnt[o];
while(q[o].size()>=&&k(q[o][q[o].size()-],q[o][q[o].size()-])<=k(q[o][q[o].size()-],i))q[o].pop_back();
q[o].push_back(i);
while(q[o].size()>=&&k(q[o][q[o].size()-],q[o][q[o].size()-])<=id[i])q[o].pop_back();
f[i]=calc(q[o][q[o].size()-],id[i]-id[q[o][q[o].size()-]]+);
}
printf("%lld",f[n]);
}

BZOJ4907

[BZOJ4907]柠檬的更多相关文章

  1. 【BZOJ-1502】月下柠檬树 计算几何 + 自适应Simpson积分

    1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: 562[Submit][Status] ...

  2. bzoj4709 [jsoi2011]柠檬

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

  3. 1502: [NOI2005]月下柠檬树 - BZOJ

    Description Input 文件的第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度).第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的 ...

  4. BZOJ 1502: [NOI2005]月下柠檬树 [辛普森积分 解析几何 圆]

    1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1070  Solved: 596[Submit][Status] ...

  5. [LeetCode] Lemonade Change 买柠檬找零

    At a lemonade stand, each lemonade costs $5.  Customers are standing in a queue to buy from you, and ...

  6. [Swift]LeetCode860. 柠檬水找零 | Lemonade Change

    At a lemonade stand, each lemonade costs $5. Customers are standing in a queue to buy from you, and ...

  7. [NOI2005]月下柠檬树(计算几何+积分)

    题目描述 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔 地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思 索着人生的哲理. 李哲是一个喜爱思考的孩子,当他看 ...

  8. bzoj4709: [Jsoi2011]柠檬 斜率优化

    题目链接 bzoj4709: [Jsoi2011]柠檬 题解 斜率优化 设 \(f[i]\) 表示前 \(i\)个数分成若干段的最大总价值. 对于分成的每一段,左端点的数.右端点的数.选择的数一定是相 ...

  9. Leetcode 860. 柠檬水找零

    860. 柠檬水找零  显示英文描述 我的提交返回竞赛   用户通过次数187 用户尝试次数211 通过次数195 提交次数437 题目难度Easy 在柠檬水摊上,每一杯柠檬水的售价为 5 美元. 顾 ...

随机推荐

  1. CentOS 6.8下安装docker并使用

    Docker是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.利用Linux的LXC.AUFS.Go语言.cgroup实现了资源的独立,可以很轻松的实现文件.资 ...

  2. 函数, lambda表达式

    函数 函数:简单的理解,就是一次执行很多行代码 函数的返回值 函数的参数,和变量没区别 例: def hello(): print "hello world" hello() he ...

  3. lxml简明教程

    最近要做下微信爬虫,之前写个小东西都是直接用正则提取数据就算了,如果需要更稳定的提取数据,还是使用 xpath 定位元素比较可靠.周末没事,从爬虫的角度研究了一下 python xml 相关的库. P ...

  4. HTC开放Vive Tracker代码啦!

    (52VR网2017年5月2日)HTC正在为工作室创建的Vive Tracker项目发布教程和项目文件,作为VR开发人员的新资源. 该公司希望能够让更多的开发者能够在开发Vive VR耳机时制作自己的 ...

  5. 关于v-model、v-for、v-on的用法

    展示Holle Vue     window.onload = function(){         var box = new Vue({             el:'#div',      ...

  6. linux 内核的spinlock

    spinlock设计成了三层,第一层是接口,第二层raw实现层,第三层是CPU平台层.在第二层raw实现层提供了两个分支,分别是单CPU和多CPU(核).第三层是不同CPU的锁操作实现.raw层除了调 ...

  7. 跨域问题解决方案(HttpClient安全跨域 & jsonp跨域)

    1 错误场景 今天要把项目部署到外网的时候,出现了这样的问题, 我把两个项目放到自己本机的tomcat下, 进行代码调试, 运行 都没有问题的, 一旦把我需要调用接口的项目B放到其他的服务器上, 就会 ...

  8. 做自己的PHP语法解释器

    PHP关键字异构化实验 PHP词法分析和语法分析 简单理解PHP代码执行过程:http://blog.csdn.net/risingsun001/article/details/22888861 PH ...

  9. Integer浅谈

    别BB,亮代码. 结果: 结果分析: 1.true 相信大家对第一个的比较结果应该不意外,只是单纯的数值比较 2.true 这个和第三个结果一比较起来就感觉迷惑了,明明两个都是同样的赋值方式,为什么一 ...

  10. 1019 Least Common Multiple

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...