能量项链(区间dp入门题)
能量项链
解题思路:这是区间dp的入门题。首先是项链是一个环,我们把他拆成一条链来看,依次枚举长度,再枚举左端点,确定右端点,再从左端点到右端点枚举中间点来更新最优值。
结合代码理解
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<LL,int>PII;
typedef unsigned long long ULL;
namespace IO{
inline LL read(){
LL o=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){o=o*10+c-'0';c=getchar();}
return o*f;
}
}using namespace IO;
const int N=207,M=N*2,INF=0x3f3f3f3f,mod=1e9+7;
int w[N];
int dp[N][N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>w[i];
w[n+i]=w[i];//此处是把一个环拆成一条链
}
for(int Len=3;Len<=n+1;Len++){//枚举长度,因为把环拆成链,所以长度最长为n+1(自行思考)
for(int L=1;L+Len-1<=2*n;L++){//在长度的限制先,保证左端点合法
int R=L+Len-1;//确定右端点
dp[L][R]=-INF;//给区间初始化
for(int k=L+1;k<R;k++){//选取中间点
dp[L][R]=max(dp[L][R],dp[L][k]+dp[k][R]+w[L]*w[k]*w[R]);//根据中间点不断更新答案
}
}
}
int res=0;
for(int i=1;i<=n;i++){
res=max(res,dp[i][i+n]);//枚举每个左端点,因为每一个位置都可以是项链的起点,取最大值
}
cout<<res<<endl;
return 0;
}