\(f_i\) 表示到第 \(i\) 只贝壳最多可以换得的柠檬数。
令 \(c_i=\sum_{h=1}^i[s_h=s_i]\)。
\[\begin{split}
f_i=&\max\{f_{j-1}+s_i(c_i-c_j+1)^2\}(s_i=s_j,j\le i)\\\\
f_i=&f_{j-1}+s_i(c_i^2+c_j^2+1-2c_ic_j+2c_i-2c_j)\\\\
f_i=&f_{j-1}+s_ic_i^2+s_ic_j^2+s_i-2s_ic_ic_j+2s_ic_i-2s_ic_j\\\\
f_{j-1}+s_jc_j^2-2s_jc_j=&2s_ic_ic_j+f_i-s_ic_i^2-2s_ic_i-s_i\\\\
\end{split}
\\
\therefore
\begin{cases}
y=f_{j-1}+s_jc_j^2-2s_jc_j\\
k=2s_ic_i\\
x=c_j\\
b=f_i-s_ic_i^2-2s_ic_i-s_i\\
\end{cases}
\\
\Huge y=kx+b
\]
搞定。
#include <bits/stdc++.h>
using namespace std;
//Start
#define re register
#define il inline
#define mk make_pair
#define pb push_back
#define db double
#define lng long long
#define fi first
#define se second
const int inf=0x3f3f3f3f;
const lng INF=0x3f3f3f3f3f3f3f3f;
//Data
const int N=10000;
int n;
vector<int> s,cnt(N+7),c;
vector<lng> f;
//DP
template<typename T>il T p2(re T x){return x*x;}
il db X(re int j){return c[j];}
il db Y(re int j){return f[j-1]+p2((lng)c[j])*s[j]-(lng)2*c[j]*s[j];}
il db slope(re int k,re int t){return (Y(t)-Y(k))/(X(t)-X(k));}
il lng F(re int i,re int j){return f[j-1]+p2((lng)c[i]-c[j]+1)*s[i];}
vector<int> que[N+7];
#define q que[R]
#define r que[R][0]
il lng DP(){
f.pb(0);
for(re int R=1;R<=N;R++) q=vector<int>(cnt[R]+7);
for(re int i=1,R=s[i];i<=n;R=s[++i]){
while(r>=2&&slope(q[r-1],i)>=slope(q[r-1],q[r])) r--; q[++r]=i;
while(r>=2&&F(i,q[r])<=F(i,q[r-1])) r--; f.pb(F(i,q[r]));
}
return f[n];
}
//Main
int main(){
scanf("%d",&n),s.pb(0),c.pb(0);
for(re int i=1,x;i<=n;i++) scanf("%d",&x),s.pb(x),c.pb(++cnt[x]);
printf("%lld\n",DP());
return 0;
}
\[\Huge\color{#ddd}{\texttt{---END---}}
\]
手机扫一扫
移动阅读更方便
你可能感兴趣的文章