这一套题的质量都非常不错。
dp[l][xl][r][xr]=minl<m<rdp[l][xl][m][xl+xr]+dp[m][xl+xr][r][xr]+(xl+xr)Am.dp[l][x_l][r][x_r] = min_{l<m<r} dp[l][x_l][m][x_l + x_r] + dp[m][x_l + x_r][r][x_r] + (x_l + x_r)A_m.dp[l][xl][r][xr]=minl<m<rdp[l][xl][m][xl+xr]+dp[m][xl+xr][r][xr]+(xl+xr)Am.
最后的答案是每一个数乘上一个系数相加而得。
dpdpdp就是计算了不同系数下的最小值。
lll,rrr表示区间的左、右边界。xlx_lxl、xrx_rxr表示lll,rrr的系数。
中间的数的系数肯定是左右两个数的系数之和。
模拟dpdpdp即可。
Code:Code:Code:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a[20];
ll dp(int l,int r,ll xl,ll xr)
{
if(l+1==r)return 0;
ll ans=1e18;
for(int i=l+1;i<r;i++)
ans=min(ans,dp(l,i,xl,xl+xr)+dp(i,r,xl+xr,xr)+(xl+xr)*a[i]);
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
printf("%lld",dp(1,n,1,1)+a[1]+a[n]);
return 0;
}