题意:给出一系列石堆,每次可以合并相邻的两堆,且每次合并的花费是这两堆石块数量和,求把这些石堆合并为一个石堆的最小花费。
题解:对于相邻的两个石堆可以选取合并或者不合并,给出状态转移方程
temp = min(temp, dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
temp是个临时值,即找最小的相邻石堆合并, 用sum[i]存储前i个石堆的石头个数之和,这样便于计算每次合并的花费。
如果还不是很懂的话可以去看看他的博客:点击打开链接
下面附上代码:
#include
#include
#include
using namespace std;
int main()
{
int n, sum[105],dp[105][105];
scanf("%d", &n);
memset(dp, 0, sizeof(dp));
sum[0] = 0;
for(int i = 1; i < n+1; i++)
{
int temp;
scanf("%d", &temp);
sum[i] = sum[i-1] + temp;
}
for(int i = n; i > 0; i--)
{
for(int j = i+1; j<=n; j++)
{
int temp = 0x3f3f3f3f;
for(int k = i; k < j; k++)
{
temp = min(temp, dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
}
dp[i][j] = temp;
}
}
printf("%d\n", dp[1][n]);
}