石子合并
-
核心思想: 区间dp
-
集合定义 : f[i][j]表示将[i,j] 合并的最小代价
-
集合计算 : 枚举 i<=k<=j 将f[i][j] (因为i到j是连续的)分为 **f[i][k] + f[k+1][j] + (s[j] – s[i–1])**三部分
-
#include<iostream> #include<cstring> #include<algorithm> using namespace std; const int N = 310; int f[N][N]; int s[N]; //前缀和数组 用于求 i -- j 总和 int n; int main() { cin>>n; for(int i=1;i<=n;i++) cin>>s[i] , s[i] += s[i-1]; //求前缀和 for(int len = 2;len<=n;len++) //遍历所有区间长度 长度为1没有代价 =0 不用初始化 { for(int i=1;i + len -1 <=n; i++) //区间左端点遍历 直到右端点 =n { int j = i + len -1; //右端点 f[i][j] = 1e8; //将该区间代价初始化无穷大 否则min永远是0 for(int k=i;k<=j;k++) //遍历区间内部 { f[i][j] = min(f[i][j] , f[i][k] + f[k+1][j] + s[j] - s[i-1]); } } } //回归定义 f[1][n]为1--n的最小代价 cout<<f[1][n]; }
-