题目描述
题解
当s=0时只用考虑相邻两个,所以设f[i,j]表示做完[i,j]的答案,转移枚举最后一个选的k
如果s!=0,那么发现多出来的i+1,i+2与i无关,所以只需要维护i+1,i+2的操作次数
按删的时间建树,则在f[i,j]中维护左链位置以及右链长度,转移就是右链个数*左链值
直接写是n^7,发现在枚举f[i,k,j1,j2],f[k,j,j3,j4]合并与j3无关,所以先枚举i,j,k,j2,j3,j4合并,之后枚举i,j,k,j1,j2,j4转移,这样是n^6
注意不会爆int
code
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define sqr(x) ((x)*(x))
#define ll long long
#define file
using namespace std;
namespace Main{
int a[72],b[72],c[72],d[72];
int f[72][72][72][72],g[72][72][72],h[72][72][72],S[72][72];
int n,i,j,k,l,j1,j2,j3,j4;
int s,ans=0,s1,s2;
int js(int t1,int t2,int t3) {return sqr(a[t1]-b[t2])+sqr(a[t2]-c[t3]);}
void main()
{
// freopen("landmine.in","r",stdin);
// #ifdef file
// freopen("landmine.out","w",stdout);
// #endif
scanf("%d",&n);
fo(i,1,n) scanf("%d",&a[i]);
fo(i,1,n) scanf("%d",&b[i]);
fo(i,1,n) scanf("%d",&c[i]);
fo(i,1,n) scanf("%d",&d[i]);
fo(i,0,n+1) fo(j,i,n+1) {S[i][j]=sqr(a[i]-d[j]); fo(k,j,n+1) h[i][j][k]=js(i,j,k);}
memset(f,254,sizeof(f));
fo(l,1,n)
{
fo(i,1,n-l+1)
{
memset(g,254,sizeof(g));
j=i+l-1;
if (l==1) f[i][j][i][1]=h[i-1][i][i+1];
else
{
fo(k,i+1,j-1)
{
fo(j3,k+1,j+1)
{
fo(j4,1,j-k)
if (f[k+1][j][j3][j4]>=0)
{
s1=f[k+1][j][j3][j4]+h[i-1][k][j+1],s2=S[k][j3];
fo(j2,1,k-i) g[j2][k][j4]=max(g[j2][k][j4],s1+s2*j2);
}
}
}
fo(j3,i+1,j+1)
{
fo(j4,1,l-1)
if (f[i+1][j][j3][j4]>=0)
s=f[i+1][j][j3][j4]+h[i-1][i][j+1],f[i][j][i][j4+1]=max(f[i][j][i][j4+1],s);
}
fo(j1,i,j)
{
fo(j2,1,l-1)
if (f[i][j-1][j1][j2]>=0)
{
s=f[i][j-1][j1][j2]+h[i-1][j][j+1]+j2*S[j][j+1];
f[i][j][j1][1]=max(f[i][j][j1][1],s);
f[i][j][j][1]=max(f[i][j][j][1],s);
}
}
fo(k,i+1,j-1)
{
fo(j1,i,k)
{
fo(j2,1,k-i)
if (f[i][k-1][j1][j2]>=0)
{
fo(j4,1,j-k)
{
s=f[i][k-1][j1][j2]+g[j2][k][j4];
f[i][j][j1][j4+1]=max(f[i][j][j1][j4+1],s);
f[i][j][k][j4+1]=max(f[i][j][k][j4+1],s);
}
}
}
}
}
fo(j1,i,j)
{
fo(j2,1,n)
f[i][j][j+1][j2]=max(f[i][j][j+1][j2],f[i][j][j1][j2]);
}
}
}
fo(j1,1,n+1) fo(j2,1,n) ans=max(ans,f[1][n][j1][j2]);
printf("%d
",ans);
}
}
int main() {Main::main();}