可以看到,其本质就是在区间 i — j 中找到一个分割点 k , 再将分割出来的两个区间 f [l][k] 以及 f [k + 1][r] 进行合并。由于 k 的值在l — r 之间,因此需要逐个列举并求出合并的最小值。根据题目意思,f [1][n] 即为包含了1 到 第n个石头的最优解。好了,现在该上代码了,可以看看代码中的解析部分。
#include<iostream>#include<algorithm>usingnamespace std;constint N =310;int n;int f[N][N];int s[N];intmain(){
scanf("%d",&n );for(int i =1; i <= n; i++)scanf("%d",&s[i]);//利用前缀和 for(int i =1; i <= n ; i++) s[i]+= s[i -1];for(int len =2; len <= n; len++)//划分区间,从2开始一直到n {
for(int i =1; i + len -1<= n ; i++)//先从1开始作为区间的左端点{
int l = i , r = l + len -1;
f[l][r]=1e8;for(int k = l ; k < r ; k++)//在已有的区间中再设立分割点k,利用前缀和进行解决
f[l][r]=min( f[l][r], f[l][k]+ f[k +1][r]+ s[r]- s[l -1]);}}
cout << f[1][n]<< endl;return0;}
作者:chenxuanqi6@163.com
链接:https://www.acwing.com/activity/content/code/content/523537/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。