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 只柠檬。没有

比这更优的方案了。

Sol

显然题目转化为序列分割问题,而且每个分出来的序列首尾肯定相同(否则去掉之后这一段贡献不变,产生了新的段使得最终答案更大),所以我们得到普及组dp:

令\(f[i]\)表示前i位的最大价值,那么:\(f[i]=f[j-1]+a[j]*(s[i]-s[j]+1)^2\),s[i]代表前i个数里a[i]出现的次数 。

tle,考虑优化。我们发现后面那个平方随着i的上升它是单调不降的,所以我们对于每个权值开个单调栈保存当前最优解的j,然后用栈顶更新即可。

每次要入栈之前,如果栈底第二个元素f值已经大于栈顶了,说明栈顶没用了,就弹出直到栈顶大于栈顶第二个元素的贡献为止。但是可能出现后面的超过栈顶但是第二个元素没超过的情况,所以我们在每次入栈之前,要先判断第二个元素和第一个元素超过当前i的时间,如果第二个超过时间比第一个早,弹出栈顶直到情况改变为止。

Code

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll f[100010];int n,a[100010];int cnt[100010],s[100010];vector<int>q[10010];
ll cal(int x,int y){return f[x-1]+(ll)a[x]*y*y;}
int sol(int x,int y)
{
int l=1,r=n,ret=n+1;
while(l<=r)
{
int mid=l+r>>1;
if(cal(x,mid-s[x]+1)>=cal(y,mid-s[y]+1)) ret=mid,r=mid-1;
else l=mid+1;
}
return ret;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);a[i]=x;s[i]=++cnt[x];
while(q[x].size()>=2&&sol(q[x][q[x].size()-2],q[x][q[x].size()-1])<=sol(q[x][q[x].size()-1],i)) q[x].pop_back();
q[x].push_back(i);
while(q[x].size()>=2&&sol(q[x][q[x].size()-2],q[x][q[x].size()-1])<=s[i]) q[x].pop_back();
f[i]=cal(q[x][q[x].size()-1],s[i]-s[q[x][q[x].size()-1]]+1);
}
printf("%lld\n",f[n]);
}

【bzoj4709】[Jsoi2011]柠檬 决策单调性+dp的更多相关文章

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

    题解: 解法1: 单调栈优化 首先发现一个性质就是 如果当前从i转移比从j转移更加优秀 那么之后就不会从j转移 所以我们考虑利用这个性质 我们要维护一个队列保证前一个超过后一个的时间单调不减 怎么来维 ...

  2. BZOJ4709: [Jsoi2011]柠檬(决策单调性)

    题意 题目链接 Sol 结论:每次选择的区间一定满足首位元素相同.. 仔细想想其实挺显然的,如果不相同可以删掉多着的元素,对答案的贡献是相同的 那么设\(f[i]\)表示到第\(i\)个位置的最大价值 ...

  3. [BZOJ4709][JSOI2011]柠檬(斜率优化DP)

    显然选出的每一段首尾都是相同的,于是直接斜率优化,给每个颜色的数开一个单调栈即可. #include<cstdio> #include<vector> #include< ...

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

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

  5. BZOJ4426 :最大生产率(贪心+决策单调性DP)

    题意:给出N个人,现在让你分P组,每组的工作效率是最小结束时间-最大开始时间,要求每一组的效率的正数,求最大效率和.N<1000 思路: 把包含至少一个其他的分到A组:否则到B组. A组的要么单 ...

  6. CF321E Ciel and Gondolas 【决策单调性dp】

    题目链接 CF321E 题解 题意:将\(n\)个人分成\(K\)段,每段的人两两之间产生代价,求最小代价和 容易设\(f[k][i]\)表示前\(i\)个人分成\(k\)段的最小代价和 设\(val ...

  7. BZOJ2216 [Poi2011]Lightning Conductor 【决策单调性dp】

    题目链接 BZOJ2216 题解 学过高中数学都应知道,我们要求\(p\)的极值,参变分离为 \[h_j + sqrt{|i - j|} - h_i \le p\] 实际上就是求\(h_j + sqr ...

  8. 洛谷 P3515 [ POI 2011 ] Lightning Conductor —— 决策单调性DP

    题目:https://www.luogu.org/problemnew/show/P3515 决策单调性... 参考TJ:https://www.cnblogs.com/CQzhangyu/p/725 ...

  9. LOJ2074/2157 JSOI2016/POI2011 Lightning Conductor 决策单调性DP

    传送门 我们相当于要求出\(f_i = \max\limits_{j=1}^{n} (a_j + \sqrt{|i-j|})\).这个绝对值太烦人了,考虑对于\(i>j\)和\(i<j\) ...

随机推荐

  1. ghld

  2. Python 中的 is 和 == 编码和解码

    一   is   与   ==   区别 ==    比较            比较的是值 例如: a = 'alex' b = 'alex' print(a == b) #True a = 10 ...

  3. krpano之鼠标样式修改

    引入cursors.js. cursors.js代码: <krpano > <events onxmlcomplete="action(qtvrcursor);" ...

  4. SqlConnection 无法设置连接超时

    1.最有效的方法:对表格建立索引 2 在连接字符串中设置 Connection Timeout (默认15秒)3 设置 SqlCommand.CommandTimeout(默认是 30 秒)

  5. Visual Studio 2005 C# 读写Excel文件

    做作业的时候查了一点儿资料, 用的vs2k5 读 excel 发现用起来非常简单...现在编程语言没话说! 项目-添加引用-COM-Microsoft Excel 12.0 Object Librar ...

  6. Apache Shiro 权限框架

    分享一个视屏教程集合 http://www.tudou.com/home/konghao/item 1.Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码 ...

  7. 编译错误error:&nbsp;invalid&amp;nbsp…

    昨天遇到一个莫名其妙的编译错误,以前没有见过,而且代码流程看起来也没有太多的奇异之处.后来忍无可忍,百度了下,发现别人也有遇到这个错误的,他的解决方法是:少了"}". 嘿嘿,我开始 ...

  8. centos6下的安装navicat premium

    centos6下的安装navicat premium CentOS6下做开发的时候,数据库客户端是一个必须要有的工具,因为经常要和数据库打交道.由于数据库的类型多样,有MySQL.Oracle.Pos ...

  9. 配置Linux的SSH双重认证

    背景:双因子认证(简称:2FA,以下简称2FA),在这里其为SSH的第二重认证.2FA指的是密码以及实物(信用卡.SMS手机.令牌或指纹等生物标志)两种条件对用户进行认证的方法.通过两种不同的认证程序 ...

  10. 【bzoj3670】[Noi2014]动物园

    3670: [Noi2014]动物园 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2080  Solved: 1107[Submit][Status ...