区间dp Simple AniPop

https://codeforces.com/gym/102878/problem/C

给定一个环,逐个删除它的所有元素。删除一个元素,若n>=2得到它与相邻左右元素乘积的价值,而n=1时只得到被删除元素的价值。求价值max

自己没想出来,面向题解且实现出错,记录如下:

状态设计:假设dp[i][j]为开区间(i,j)均被消除,但端点仍然保留的价值。其中,j=i与i+1都是0,j=i+n时情况特殊,dp[i][i+n]+a[i]为最后消去a[i]的方案的最大值(这一点有点跳跃,需要对倒数第二次消除脑内模拟)

技巧:化环成链,paste。

 

dp实现的时候要保证访问到的状态已经最优,所以这里先枚举长度,根据区间枚举左右端点,要保证全部覆盖。

若0<=i,j<=n,虽然paste后dp[i][j]和dp[i+n][j+n]一样,但是由于之后骑缝的情况中需要调用,所以一样要记录。

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[1010],dp[1010][1010];
int main(){
	int n,res;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		a[i+n]=a[i];
		//res=a[i];
	}
	for(int l=1;l<=n;l++)
		for(int i=1;l+i<=2*n;i++)
		{
			int j=l+i;
			//int mx=max(a[i],a[j]),mn=min(a[i],a[j]);
			for(int k=i+1;k<=j-1;k++)
				dp[i][j]=max(dp[i][j],dp[i][k]+dp[k][j]+a[k]*a[i]*a[j]);
			if(j==i+n)
			res=max(dp[i][j]+a[i],res);
		}
	printf("%d\n",res);
	return 0;
}

  

posted @ 2021-02-03 22:08  难以理解  阅读(127)  评论(0)    收藏  举报