【THUSC2016】成绩单

题面

https://loj.ac/problem/2292

题解

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

我们发现每一次取出的区间一定要么不交要么完全覆盖的。可以看成构成了一个树的$dfs$序的结构,这也许和【NOI2009】二叉查找树之间有些关系。

不难发现每次的代价只与最小值和最大值有关,

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

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

转移的话,是一个常见的套路,即考虑最后的分割点(树形$dp$转序列$dp$\多叉树转二叉树一样的套路)

具体的说,枚举最后的分割点$d$,把$d$左侧和$d$右侧的区间合并,有$$f[i][j][min(x,w[j])][max(y,w[j])]=min\{f[i][d-1][x][y]+f[d][j-1][0][0]\}$$

对于某区间,最后一次的转移,即放上一个最大的区间,$$f[i][j][0][0]=min\{f[i][j][x][y]+a+b(y-x)^2\}$$

#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;
}

 

posted @ 2019-11-04 15:37  HellPix  阅读(166)  评论(0编辑  收藏  举报