原题链接:https://www.nowcoder.com/question/next?pid=28665343&qid=1371128&tid=52589195
#include <bits/stdc++.h>
using namespace std;
//dp状态已当前节点p为根,左右区间范围为[l,r] 的子树的最小权值和
//状态转移:dp[i][j] = 左区间 + 有区间 + 两点之积
//方便状态转移 取结点0为根 则从dfs(1,n,0)递归
int dp[305][305][305];
int a[305];
int n;
int dfs(int l,int r,int p)
{
if(l > r) return 0;
if(dp[l][r][p] != -1) return dp[l][r][p];//剪枝操作
int res= 2e9;
for(int i = l; i <= r; i++)//枚举每个根节点
{
int left = dfs(l,i-1,i);//左子树
int right = dfs(i+1,r,i);//右子树
res = min(res,left + right + a[i] * a[p]);
}
dp[l][r][p] = res;
return res;
}
int main()
{
cin>>n;
for(int i = 1; i <= n; i++) cin>>a[i];
memset(dp,-1,sizeof(dp));//初始化
cout << dfs(1,n,0) << "\n";
return 0;
}