1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include<bits/stdc++.h> using namespace std; #define int long long inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'|| ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;} #define Z(x) (x)*(x) #define pb push_back
#define N 3010
struct Num { int x, id; }mx[N][22], mn[N][22]; int n, m, i, j, k, T; int a[N], Log2[N]; map<pair<int, int>, int>f[N];
Num max(Num a, Num b) { return (a.x>b.x ? a : b); }
Num min(Num a, Num b) { return (a.x<b.x ? a : b); }
Num Mx(int l, int r) { int k = Log2[r-l+1]; return max(mx[l][k], mx[r-(1<<k)+1][k]); }
Num Mn(int l, int r) { int k = Log2[r-l+1]; return min(mn[l][k], mn[r-(1<<k)+1][k]); }
int S(int r, int n) { int l = r - n + 1; return (l+r)*n/2; }
int dfs(int l, int r, int k) { if(l>r) return 0; if(f[l].find({r, k})!=f[l].end()) return f[l][{r, k}]; Num x, y; x=Mx(l, r); y=Mn(l, r); int ans=1e18;
ans=min(ans, a[x.id]-k+dfs(l, x.id-1, k)+dfs(x.id+1, r, k)); ans=min(ans, S(a[x.id]-k, a[y.id]-k)+dfs(l, y.id-1, a[y.id])+dfs(y.id+1, r, a[y.id])); return f[l][{r, k}]=ans; }
signed main() {
freopen("cake.in","r",stdin); freopen("cake.out","w",stdout);
n=read(); for(i=1; i<=n; ++i) a[i]=read(); for(i=1; i<=n; ++i) mx[i][0].x=a[i], mx[i][0].id=i; for(i=1; i<=n; ++i) mn[i][0].x=a[i], mn[i][0].id=i; for(i=2; i<=n; ++i) Log2[i]=Log2[i>>1]+1; for(k=1; k<=20; ++k) for(i=1, j=(1<<k-1)+1; i+(1<<k)-1<=n; ++i, ++j) mx[i][k]=max(mx[i][k-1], mx[j][k-1]), mn[i][k]=min(mn[i][k-1], mn[j][k-1]); printf("%lld", dfs(1, n, 0)); return 0; }
|