题目:
有一堆石子,编号为1,2,3……N
每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和
找到一种方案使总代价最小
举个例子:
1 3 5 2
第一种方案:
先合并第1,2堆====>4 4 5 2
再合并第1,2堆====>9 9 2
再合并第1,2堆====>11 11
这一种方案的总代价 : 4+9+11 = 24
第二种方案:
先合并第1,2堆====>4 4 5 2
再合并第2,3堆====>7 4 7
再合并第1,2堆====>11 11
这一种方案的总代价 : 4+7+11 = 22
分析:
代码:
#include<iostream>
using namespace std;
const int N = 310;
int n;
int s[N];//前缀和
int dp[N][N];
int main(){
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;i + len -1 <= n;i++){//枚举左端点
int j = i+len-1;//枚举右端点
dp[i][j] = 1e8;
for(int k = i;k < j;k++){
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+s[j]-s[i-1]);
}
}
}
cout << dp[1][n];
return 0;
}