有n堆石子,要合并成一堆,规则是只能和相邻的合并,每次合并的代价是合并出的石子堆的石子数量,求最小花费。
IN:
4
4 4 5 9
OUT:
43
直接贪心只能取到局部的最佳结果。
方程是很明显的,dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k+1][j] + sum[j] - sum[i] + s[i];
dp数组代表合并从i到j的最小花费
sum 代表前缀和
s 每堆石子的数量
区间长度从小到大递推。
#include <bits/stdc++.h>
#define INF 0x3f3f3f
using namespace std;
int dp[10][10];
int sum[10];
int s[10];
int n;
int main()
{
cin >> n;
for(int i = 1 ; i <= n ; i++)
{
cin >> s[i];
sum[i] = sum[i-1] + s[i];
}
for(int l = 1; l < n ; l++)
{
for(int i = 1; i + l <= n ;i++)
{
int j = i + l;
dp[i][j] = INF;
for(int k = i; k <= j ; k ++)
{
dp[i][j] = min(dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1] , dp[i][j]);
}
}
}
cout << dp[1][n] << endl;
return 0;
}