求一段区间的最小价值。因为每次只能合并相邻两堆石子,所以跟区间合并的贪心问题略有区别。因为是每次合并两端相邻石子堆,所以最后一定也剩下左右两堆合并。所以利用分而治之的思想。每次都寻找合并价值最小的石子堆,最后也就能求出总的石子堆合并的最小价值。
#include <iostream>
#include <algorithm>
using namespace std;
const int N=310;
int f[N][N],s[N];//区间i~j的和,前缀和
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s[i];
s[i]+=s[i-1];
}
for(int len=2;len<=n;len++)
{
for(int i=1;len+i-1<=n;i++)
{
int j=len+i-1;
f[i][j]=1e9;
for(int k=i;k<j;k++)
{
f[i][j]=min(f[i][j],s[j]-s[i-1]+f[i][k]+f[k+1][j]);
}
}
}
cout<<f[1][n];
return 0;
}