luogu1063:区间dp

luogu1063

题解

  • 类似矩阵最优连乘。
  • 因为是环,所以再复制一份加在数组后面。
  • dp[i][j]表示起始位置是i,末尾是j的最大值。因为长的区间取决于短的区间。所以区间的长度要从小到大枚举。然后再枚举区间的起始位置,这样子末尾就确定了。然后枚举中间位置分割。
  • 第i个柱子由p1✖p2构成,我们统一a[i]表示第i个柱子的前一个数即p1。
  • 状态转移:dp[i][j] = max(dp[i][j],dp[i][k] + dp[k+1][j] + a[i-1] * a[k] * a[j]);

代码

#include <bits/stdc++.h>
using namespace std;
int const N = 200;
int const inf = 0x7f7f7f7f;
int a[N<<1],n;
int dp[N<<1][N<<1];
int main(){	
	scanf("%d",&n);
	int ans = 0;
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
		a[i+n] = a[i];
	}
	for(int len=2;len<=n;len++){
		for(int i=1;i<=2*n-1;i++){   //区间的起始位置
			int j = i + len - 1;	//区间的末尾
			for(int k=i;k<j;k++)	dp[i][j] = max(dp[i][j],dp[i][k] + dp[k+1][j] + a[i-1] * a[k] * a[j]);
			if(len == n)	ans = max(ans,dp[i][i+n-1]);
		}
	}
	cout<<ans<<endl;
	return 0;
}

 

posted @ 2019-04-10 23:19  月光下の魔术师  阅读(16)  评论(0)    收藏  举报