船送门 用四边形不等式优化的区间 D P DP DP。 至于四边形不等式,特征一般都很明显,而且这东西很偏。记结论,然后给决策点打表找规律就行了吧。 由决策点的单调性把 O ( n 3 ) O(n^3) O(n3)优化成 O ( n 2 ) O(n^2) O(n2)。
#include<bits/stdc++.h> #define ll long long #define re register #define cs const cs int N=5e3+10; cs ll oo=1e18; namespace IO{ cs int Rlen=1<<22|1; char buf[Rlen],*p1,*p2; inline char gc(){return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;} template<typename T> inline T get(){ char ch=gc();T x=0; while(!isdigit(ch)) ch=gc(); while(isdigit(ch)) x=(x+(x<<2)<<1)+(ch^48),ch=gc(); return x; } inline int gi(){return get<int>();} inline ll gl(){return get<ll>();} } using IO::gi; using IO::gl; int n;ll val[N][N],sum[N],pos[N][N]; int i,L,R,len,mid; int main(){ // freopen("tree.in","r",stdin); // freopen("tree.out","w",stdout); n=gi(); for(i=1;i<=n;++i) pos[i][i]=i,val[i][i]=gl(),sum[i]=sum[i-1]+val[i][i]; for(len=2;len<=n;++len){ for(L=1;(R=L+len-1)<=n;++L){ val[L][R]=oo; for(mid=pos[L][R-1];mid<=pos[L+1][R];++mid) if(val[L][R]>val[L][mid-1]+val[mid+1][R]) val[L][R]=val[L][mid-1]+val[mid+1][R],pos[L][R]=mid; val[L][R]+=sum[R]-sum[L-1]; } }printf("%lld\n",val[1][n]); }