题目链接

思路

首先,最优秀的分法一定是每段两端都是这一段中最多的那个,否则可以把不是的那个踢出去单独成段肯定会更优秀。然后就成了将这个序列分段,保证每段两端元素相同的最大收益和。

用a[i]记录第i个位置上的数,用s[i]记录前i个元素中a[i]出现的次数。f[i]表示以前i个数的最大收益。

首先考虑\(n^2\)的dp。明显\(f[i]=max\{f[j]+a[i]*(s[i]-s[j]+1)^2\} (a[i]==a[j])\)

	for(int i=1;i<=n;++i)
for(int j=1;j<=i;++j)
if(a[i]==a[j])
f[i]=max(f[i],f[j-1]+a[i]*(s[i]-s[j]+1)*(s[i]-s[j]+1));

然后可发现,在上面的式子中,s数组是单增的,f数组也是单增的。如果知道了两个位置x和y(x<y)。通过二分,可以找到一个now使得当以后的某个位置pos的s[pos]>now之后的所有位置用x转移会比y优秀,这时y就没用了。所以用一个单调栈维护即可。

\(O(n^2)\)代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const int N=100000+100;
ll read() {
ll x=0,f=1; char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int n;
int a[N],s[N],c[N];
ll f[N];
int main() {
n=read();
for(int i=1;i<=n;++i) {
a[i]=read();
s[i]=++c[a[i]];
}
for(int i=1;i<=n;++i)
for(int j=1;j<=i;++j)
if(a[i]==a[j])
f[i]=max(f[i],f[j-1]+a[i]*(s[i]-s[j]+1)*(s[i]-s[j]+1));
cout<<f[n];
return 0;
}

\(O(n)\)代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<map>
#include<bits/stdc++.h>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const int N=100000+100;
ll read() {
ll x=0,f=1; char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
vector<int> sta[N];
int a[N],s[N],c[N];
ll f[N];
ll calc(int x,int y) {
return f[x-1]+(ll)a[x]*y*y;
}
int n;
int find(int x,int y) {//寻找x比y优秀的最早时间
int l=1,r=n;
int ans=n+1;
while(l<=r) {
int mid=l+r>>1;
if(calc(x,mid-s[x]+1)>=calc(y,mid-s[y]+1)) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}
int main() {
n=read();
for(int i=1;i<=n;++i) {
a[i]=read();
s[i]=++c[a[i]];
}
for(int i=1;i<=n;++i) {
while(sta[a[i]].size()>=2&&find(sta[a[i]][sta[a[i]].size()-1],i)>=find(sta[a[i]][sta[a[i]].size()-2],sta[a[i]][sta[a[i]].size()-1]))
sta[a[i]].pop_back();
sta[a[i]].push_back(i);
while(sta[a[i]].size()>=2&&find(sta[a[i]][sta[a[i]].size()-2],sta[a[i]][sta[a[i]].size()-1])<=s[i]) {
sta[a[i]].pop_back();
}
int now=sta[a[i]].size();
f[i]=calc(sta[a[i]][now-1],s[i]-s[sta[a[i]][now-1]]+1);
}
cout<<f[n];
}

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

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

    目录 前言吐槽 思路 错误 代码 /* 前言吐槽 我真的不知道是咋做的 不过大约就是栈的斜率优化 哪位大佬见识广,给看看吧(乞讨) 思路 s是值等于a[i]的前缀和 转移方程$f[i]=max(f[i ...

  2. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

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

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

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

    [BZOJ4709]柠檬(动态规划,单调栈) 题面 BZOJ 题解 从左取和从右取没有区别,本质上就是要分段. 设\(f[i]\)表示前\(i\)个位置的最大值. 那么相当于我们枚举一个前面的位置\( ...

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

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

  6. bzoj4709 [jsoi2011]柠檬

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

  7. 【bzoj4709】[Jsoi2011]柠檬 斜率优化

    题目描述 给你一个长度为 $n$ 的序列,将其分成若干段,每段选择一个数,获得 $这个数\times 它在这段出现次数的平方$ 的价值.求最大总价值. $n\le 10^5$ . 输入 第 1 行:一 ...

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

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

  9. BZOJ4709 JSOI2011柠檬(动态规划)

    首先要冷静下来发现这仅仅是在划分区间.显然若有相邻的数字相同应当划分在同一区间.还有一个显然的性质是区间的两端点应该相同且选择的就是端点的数.瞬间暴力dp就变成常数极小100002了.可以继续斜率优化 ...

随机推荐

  1. mysql 通过慢查询日志查写得慢的sql语句

    MySQL通过慢查询日志定位那些执行效率较低的SQL 语句,用--log-slow-queries[=file_name]选项启动时,mysqld 会写一个包含所有执行时间超过long_query_t ...

  2. hive基础操作—(1)

    执行./hive命令后,进入CLI(shell)模式: 1.创建数据库,语句: create database school; 2.展示所有的数据库,语句: show databases; 3.选择使 ...

  3. Python基础系列讲解——random模块随机数的生成

    随机数参与的应用场景大家一定不会陌生,比如密码加盐时会在原密码上关联一串随机数,蒙特卡洛算法会通过随机数采样等等.Python内置的random模块提供了生成随机数的方法,使用这些方法时需要导入ran ...

  4. Bing词典分析

    0x01 Bug测试结果 本次测试的是Bing词典wp版本V4.5.2,经过测试,共发现如下Bug. 1.更新后,旧版本首页的每日单词与文章推荐不能重新获得,部分搜索历史记录丢失. 2.在单词挑战模式 ...

  5. linux内实践核分析模块

  6. Java web错误总结~

    1.java程序中没有错,但是项目上面显示一个红叉的解决办法 错误信息: 报Description  Resource Path Location Type Java compiler level d ...

  7. beanutils的使用

    在项目进行中,使用到beanutils时发现1.9.X以上版本搭配logging搭配使用用不了,实在搞不明白.----stackoverflow提问吧 BeanUtils工具由Apache软件基金组织 ...

  8. Xshell连接到centos提示Could not connect to (port 22): Connection failed

    关于XShell连接虚拟机中的centos系统的问题,在连接的时候报错如下: 一开始以为是系统的问题,但是搞了很久,才发现是虚拟机这个软件本身的问题,的确坑啊!所以解决方法也很简单.在编辑菜单那里打开 ...

  9. SpringMvc常见问题汇总

    1.Service类未用@Service注解2016-10-26 17:31:36 [org.springframework.web.context.ContextLoader]-[ERROR] Co ...

  10. Axios插件和loading的实现

    axios插件就是一个ajax插件 axios具有ajax的所有方法如 get post delete put等等的方法 使用时只需要引入即可 如import Axios form 'axios' 不 ...