Stone merge (range dp template title)

There are stones piled n, the i ai a reactor with stones. These should now be merged into a pile of stones, you can only merge two adjacent, each merger cost is the total number of gravel piles of stones. The combined cost of all the minimum requirements stones.

Input
The first row contains an integer T (T <= 50), it indicates the number of data sets.
Each data row comprises a first integer n (2 <= n <= 100), represents the heap of stones.
The second line contains n positive integers ai (ai <= 100), each pile represents gravel stones.

Output
of each data line only, represents the smallest merging cost.

Sample Input
2
4
1 2 3 4
5
3 5 2 1 4
Sample Output
19
33

Thinking: dp [i] [j] denotes the i-th stack stones incorporated into the cost of the j-th smallest stones piled needed
it can be obtained recursive formula: dp [i] [j] = min (dp [i] [j], dp [i] [k] + dp [k + 1] [j] + sum)
where i <= k <j, sum ij represents the total number of stones, the available sum [j] -sum [i] represents, sum array is prefix and an array

AC Code:

#include<iostream>
using namespace std;
#define N 105
#define inf 0x3f3f3f3f
int dp[N][N];
int sum[N];
int main()
{
	int t,n;
	cin>>t;
	while(t--)
	{
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&sum[i]);
			sum[i]+=sum[i-1];  //求出前缀和
		}
		for(int len=1;len<=n;len++)  //枚举区间长度
		{
			for(int i=1;i+len<=n;i++)  //注意不能越界
			{
				int j=i+len;
				dp[i][j]=inf;
				for(int k=i;k<j;k++)
					dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
			}
		}
		cout<<dp[1][n]<<endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43693379/article/details/90725092