状态计算:每次划分 从左边 合并 1 堆 直到合并 k - 1 堆(右边要留一堆)。
状态方程: 按 左边 k 来划分,把左边的合并成本+右边的合并成本+最后两堆合并的成本。
#include<iostream> using namespace std; const int N=310; int s[N];//记录前缀和 int f[N][N];//f[l][r]表示从l到r合并成一堆的最小代价 int main() { int n;//石子堆数 cin>>n; for(int i=1;i<=n;i++) cin>>s[i];//记录每堆石子的质量 for(int i=1;i<=n;i++) s[i]+=s[i-1];//算前缀和 for(int len=2;len<=n;len++)//阶段:枚举区间长度 for(int l=1;l+len-1<=n;l++)//长度:枚举区间起点 { int r=l+len-1;//区间终点 f[l][r]=1e9; for(int k=l;k<r;k++)//决策:枚举分割点 每次分割 l,l+1,……,r-1 f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]+s[r]-s[l-1]); } cout<<f[1][n]<<endl; return 0; }