题意:
给出一系列数字,除了头尾不能动,每次去除一个数字,这个数字左右相邻数字的乘积是其价值,最后将所有价值加起来,要求最小值
d[i][j]表示第i个数到第j个数合并的最小值
状态转移方程:
d[i][j]=min(d[i][j],d[i][k]+d[k][j]+a[i]*a[j]*a[k])
只能说dp博大精深,实在不懂手动模拟一下就懂了,还需练习啊
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 106;
const int INF = 0x3f3f3f3f;
int dp[maxn][maxn];
int num[maxn];
int main()
{
int n;
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>num[i];
}
for(int len=2; len<=n; len++) //区间长度
{
for(int i=1; i+len<=n; i++) //起点
{
int j=i+len;
dp[i][j]=INF;
for(int k=i+1; k<j; k++)
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+num[i]*num[k]*num[j]);
}
}
cout<<dp[1][n]<<endl;
return 0;
}