问题描述:
设有n堆沙子,其编号为A1,A2,A3……An,每堆沙子都有一定的数量,例如:
13 7 8 16 21 4 18
现在要将n堆沙子归并成一堆,归并的过程为每次只能将相邻的两堆沙子堆成一堆,这样经过n-1次归并后成为一堆。
归并的代价是这样定义的:将两堆沙子归并为一堆时,两堆沙子的数量的和称为归并两堆沙子的代价。
问题:但n堆沙子的数量给出之后,找出一种合理的归并方法,使总的归并代价为最小。
输入样例:
13 7 8 16 21 4 18
输出样例:
239
区间dp,枚举切开的位置
dp(i,j)=dp(i,k)+dp(k+1,j)+sum[i,k]+sum[k+1,j]; i<=k<=j-1 ,当i==j时dp(i,j)=0;
预先处理sum,表示i到j的和
int[][]
sum=new int[n+1][n+1];
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
for(int k=i;k<=j;k++)
sum[i][j]+=num[k];
DP部分
public
static int dp(int[] num,int start,int end,int[][] sum)
{
if(start==end)
return 0;
int min=Integer.MAX_VALUE;
for(int k=start;k<=end-1;k++)
{
int temp=dp(num, start, k,sum)+dp(num,k+1,end,sum)+sum[start][k]+sum[k+1][end];
if(temp<min)
min=temp;
}
return min;
}