6894. 【2020.11.25提高组模拟】小 S 埋地雷(landmine)/loj #6611. 摧毁时间线

题目描述

https://loj.ac/p/6611

题解

当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\n",ans);
	}
}
int main() {Main::main();}
posted @ 2020-11-25 20:42  gmh77  阅读(259)  评论(0编辑  收藏  举报