题目:
Description
现在有n堆石子,第i堆有ai个石子。现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数。求合并所有石子的最小代价。
Input
第一行包含一个整数T(T<=50),表示数据组数。
每组数据第一行包含一个整数n(2<=n<=100),表示石子的堆数。
第二行包含n个正整数ai(ai<=100),表示每堆石子的石子数。
Output
每组数据仅一行,表示最小合并代价。
Sample Input
2 4 1 2 3 4 5 3 5 2 1 4
Sample Output
19 33
递归公式:见代码注释
代码:
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int a[100];
int s[100][100];
int sum(int i, int j)
{
int count1 = 0;
for (int a1 = i; a1 <= j; a1++) count1 += a[a1];
return count1;
}
int dp(int x, int y)
{
if (x >= y) return 0; //x=y时 dp(x,y)=0
if (s[x][y] >= 0) return s[x][y];
int minnum = 0x3fffffff;
for (int i = x; i < y; i++)//x<y时 dp(x,y)=min(dp(x,k)+dp(k+1,y))+sum(x,y),且x<=k<y
minnum = min(minnum, dp(x, i) + dp(i + 1, y) + sum(x, y));
s[x][y] = minnum;
return s[x][y];
}
int main()
{
int T, n;
cin >> T;
while (T--)
{
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
memset(s, -1, sizeof(s));
cout << dp(0, n - 1) << endl;
}
return 0;
}