题面

https://loj.ac/problem/2292

题解

跟$\mbox{Gloid}$爷做的一道神仙区间$dp$题。

设$f[l][r][x][y]$为取区间$[l..r]$,剩下的最大值为$x$,剩下的最小值为$y$,且右端点$r$一定还没有发的最小代价。

特别的,设$f[l][r][0][0]$为取完区间$[l..r]$的最小代价。

转移时,枚举中间点$d$,有$$f[i][j][min(x,w[j])][max(y,w[j])]=min(f[i][j][min(x,w[j])][max(y,w[j])],f[i][d-1][x][y]+f[d][j-1][0][0])$$

对于某区间,最后一次的转移需要特判,$$f[i][j][0][0]=min(f[i][j][0][0],f[i][j][x][y]+a+b*(y-x)*(y-x))$$

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ri register int
#define N 55
#define LL long long
using namespace std;

int n,a,b;
int w[N],nw[N];
LL f[N][N][N][N];

int main() {
    cin>>n;
    cin>>a>>b;
    for (ri i=1;i<=n;i++) cin>>w[i],nw[i]=w[i];
    sort(nw+1,nw+n+1);
    int t=unique(nw+1,nw+n+1)-nw-1;
    for (ri i=1;i<=n;i++) w[i]=lower_bound(nw+1,nw+t+1,w[i])-nw;
    memset(f,0x3f,sizeof(f));
    for (ri i=1;i<=n+1;i++) {
        f[i][i-1][0][0]=0;
        for (ri x=1;x<=t;x++)
            for (ri y=x;y<=t;y++) f[i][i-1][x][y]=0;
    }
    for (ri k=1;k<=n;k++)
        for (ri i=1;i<=n-k+1;i++) {
            int j=i+k-1;
            for (ri x=1;x<=t;x++)
                for (ri y=x;y<=t;y++)
                    for (ri d=i;d<=j;d++)
                        f[i][j][min(x,w[j])][max(y,w[j])]=min(f[i][j][min(x,w[j])][max(y,w[j])],f[i][d-1][x][y]+f[d][j-1][0][0]);
            for (ri x=1;x<=t;x++)
                for (ri y=x;y<=t;y++)
                    f[i][j][0][0]=min(f[i][j][0][0],f[i][j][x][y]+a+b*(nw[y]-nw[x])*(nw[y]-nw[x]));
        }
    cout<<f[1][n][0][0]<<endl;
    return 0;
}
01-12 06:41