https://vjudge.net/contest/409059#problem/D
D - Multiplication Puzzle
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e2+5;
int n;
int a[maxn],dp[maxn][maxn];
//dp[i][j]记录移除从区间[i,j]之间移除所有数(不包括端点),所花费的最小代价。
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(dp,0x3f,sizeof(dp));
//由于是求最小值,所以要初始化为inf。
//注意:这样初始化后,当i+1=j时(即i与j相邻),dp[i][j]为inf,故在下面的更新时,在考虑分割后左边和右边两个区间的花费时,要判断左右两个区间是否移除过值,如果没有移除过,就不可以加上。
for(int l=3;l<=n;l++){
//长度从3开始,因为是只有至少区间有3个值,才可以移除区间中间的数,这时的dp值才有效,记录的为移除区间端点之间所有的数所花费的代价
for (int i=1;i<=n;i++){
int j=i+l-1;//j为区间右端点
if(j>n) break;
for (int k=i+1;k<=j-1;k++){
int temp=a[i]*a[j]*a[k];
//若移除a[k]所需要的花费
if(i+1<k) temp+=dp[i][k];
if(k+1<j) temp+=dp[k][j];
//如果左右两个区间能够移除值(端点非相邻),则加上两边区间移除所花费的最小代价
dp[i][j] = min(dp[i][j],temp);
}
}
}
printf("%d\n",dp[1][n]);
//输出从1到n这个区间移除中间所有值所花费的最小代价
}
return 0;
}