poj1651 区间dp
转移方程是dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+mul[i][k][j]);
k是中间的那个数,每次更新k的值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-7; const int N=100+10,maxn=60000+10,inf=0x3f3f3f; ll dp[N][N],a[N],mul[N][N][N]; int main() { ios::sync_with_stdio(false); cin.tie(0); ll n; cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) for(int k=j+1;k<=n;k++) mul[i][j][k]=a[i]*a[j]*a[k]; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(i+1==j)dp[i][j]=0; else if(i+2==j)dp[i][j]=mul[i][i+1][i+2]; else dp[i][j]=1e18; } } for(int len=2;len<=n;len++) { for(int i=1,j=len;j<=n;i++,j++) { for(int k=i+1;k<=j-1;k++) { // cout<<dp[k][j]<<" "<<i<<" "<<k<<" "<<j<<endl; dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+mul[i][k][j]); } } } cout<<dp[1][n]<<endl; return 0; } /******************** 4 10 1 50 5 ********************/