Description
Flute likes lemons very much. It prepared a string of shells strung with twigs, intending to turn shells into lemons with a magic. A total of N shells (1≤n
≤100,000) only, sequentially strung on the branches. For convenience, we give the shell a number 1..N from left to right. The size of each shell is not necessarily the same,
The size of Shell I is Si (1≤si≤10,000). The magic of changing lemons requires that Flute remove a small continuous shell from one end of the branch and
Choose the size of a shell s0. If this small shell has a T-s0 in size, then magic can turn this small shell into s
0t^2 only lemons. Flute can take any number of shells, until the shells on the branches are all taken out. Each small segment, the Flute selected shell size S
0 can be different. The number of lemons in the final Flute is the sum of all the small slices of lemon. Flute want to know that it can use this string of shells at most
How many lemons to change. Please help solve this problem.
Solution
First guess the conclusion: the color of the beginning and end of each paragraph is the same, and the color of the selection must be the beginning of the color
This gives you the DP-type \ (F[i]=min (f[j-1]+a[i]* (s[i]-s[j]+1) ^2), a[i]==a[j]\)
This thing has decision Monotonicity, because the square function grows fast, so the front position must be more and more big behind
Each of the following numbers is the subscript, which is roughly distributed:
333222111111
Every time we judge whether a decision can be overwritten by another decision, if we can just bounce off the element and maintain it with a monotonic stack
Find the dividing point can be found in two points, can also be directly pressed in the stack, reduce the constant
#include<bits/stdc++.h>#define p (S[o].size()-1)#define q (S[o].size()-2)using namespace std;typedef long long ll;const int N=1e5+10;int n,a[N],id[N],c[N];ll f[N];vector<int>S[N/10];inline ll g(int x,int y){return f[x-1]+1ll*a[x]*y*y;}inline int k(int x,int y){ int l=1,r=n,mid,ret=n+1; while(l<=r){ mid=(l+r)>>1; if(g(x,mid-id[x]+1)>=g(y,mid-id[y]+1))ret=mid,l=mid+1; else r=mid-1; } return ret;}int main(){ freopen("pp.in","r",stdin); freopen("pp.out","w",stdout); scanf("%d",&n); for(int i=1,o;i<=n;i++){ scanf("%d",&a[i]);o=a[i];id[i]=++c[o]; while(S[o].size()>=2 && k(S[o][p],S[o][q])<=k(i,S[o][p]))S[o].pop_back(); S[o].push_back(i); while(S[o].size()>=2 && k(S[o][p],S[o][q])<id[i])S[o].pop_back(); f[i]=g(S[o][p],c[o]-id[S[o][p]]+1); } cout<<f[n]<<endl; return 0;}
Bzoj 4709: [Jsoi2011] Lemon