【THUSC2016】成绩单
题面
题解
跟$\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; }