输入
第一行为一个整数n,且1<n≤100,表示有n堆沙子,第二行为n堆魔法石的数量。
输出
一个整数,即最小代价。
样例输入
7
13 7 8 16 21 4 18
样例输出
239
【思】
dp[i][j]:从点i到点j的区间的最小代价;
p[i][j]:记录着为了计算dp[i][j]所需的中间点k,记忆化,使得时间优化到O(n^2).
#include <bits/stdc++.h>
using namespace std;
const int INF = 2147483647;
const int N = 105;
int f[N][N],p[N][N],sum[N],n,len,i,j,tmp,k,t;
int main()
{
scanf("%d",&n);
for (i=1;i<=n;++i) scanf("%d",&j),sum[i]=sum[i-1]+j,p[i][i]=i;
for (len=1;len<n;++len)
{
for (i=1;i+len<=n;++i)
{
t=i+len;
tmp=INF;
for (j=p[i][t-1];j<=p[i+1][t];++j)
if (f[i][j]+f[j+1][t]+sum[t]-sum[i-1]<tmp)
{
tmp=f[i][j]+f[j+1][t]+sum[t]-sum[i-1];
k=j;
}
f[i][t]=tmp;
p[i][t]=k;
}
}
printf("%d\n",f[1][n]);
return 0;
}