又是一道神仙题,我还是太菜了不看题解完全写不出来,其实想到了怎么定状态之后还是比较容易推下去的。
首先思考一下数据范围:n≤50,而最极端的时间复杂度是:O(n5),所以我们在定状态的时候就不要担心数组维数过大,放心去做吧。
g[i][j]表示消除区间[i,j]的最小代价。
f[l][r][a][b]表示消除区间[l,r]并且最后一次消除区间的最小值为a,最大值为b的最小代价。
考虑区间合并:
g[i][j]={f[i][k][a][b]+g[k+1][j]+A+B∗(b−a)2}
然后我们枚举f的第三维和第四维来进行更新:
f[i][j][min(a,w[j])][max(b,w[j])]=min\{f[i][k][a][b]+g[k+1][j-1]\}
最后的答案就为:g[1][n]
注意的地方,f的大小是50*50*1000*1000B=2500MB->MLE,但是很显然第三维第四维可以离散化来优化空间:50^4B=6.25MB->AC
#include <bits/stdc++.h>
#define For(I,L,R) for(int I=(L);I<=(R);I++)
#define ForDown(I,L,R) for(int I=(L);I>=(R);I--)
using namespace std;
inline int Read(){
int X=0;char CH=getchar();bool F=0;
while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
return F?-X:X;
}
const int Max=55;
const int Inf=1e9;
int N,A,B,W[Max],Id[Max];
int G[Max][Max],F[Max][Max][Max][Max];
#define Update(X,Y) ((X)=((X)>(Y))?(Y):(X))
int main(){
N=Read();
A=Read(),B=Read();
For(I,1,N) W[I]=Id[I]=Read();
sort(W+1,W+1+N);
int Len=unique(W+1,W+1+N)-W-1;
For(I,1,N) Id[I]=lower_bound(W+1,W+Len+1,Id[I])-W;
For(I,1,N) For(J,1,N) G[I][J]=Inf;
For(I,1,N) For(J,1,N) For(K,1,N) For(L,1,N) F[I][J][K][L]=Inf;
For(I,1,N) F[I][I][Id[I]][Id[I]]=G[I+1][I]=0;G[1][0]=0;
ForDown(L,N,1) For(R,L,N) For(I,1,Len)
For(J,I,Len){
if(F[L][R][I][J]==Inf) continue;
For(K,R+1,N) Update(F[L][K][min(I,Id[K])][max(J,Id[K])],F[L][R][I][J]+G[R+1][K-1]);
For(K,R,N) Update(G[L][K],F[L][R][I][J]+G[R+1][K]+A+B*(W[J]-W[I])*(W[J]-W[I]));
}
printf("%d",G[1][N]);
return 0;
}