问题 F: 石子合并问题
[命题人 : 201501010119]
时间限制 : 1.000 sec 内存限制 : 128 MB
题目描述
在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数。求把所有石子合并成一堆的最小花费。例如:输入{1,2,3,4,5},输出33。【3+6+9+15=33】
输入
本题应该处理到文件尾,每组输入包括两行,第一行为石子堆的个数n,第二行则为每堆石子的个数。
输出
输出最小花费。
样例输入 Copy
5
1 2 3 4 5
样例输出 Copy
33
import java.util.Scanner;
public class shizi {
static int m[][];
static int p[];
static int sum[];
static int n;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
n=sc.nextInt();
p=new int[n+1];
sum=new int[n+1];//第一堆累加到第i堆的总费用
m=new int[n+1][n+1];
for(int i=1;i<=n;i++) {
p[i]=sc.nextInt();//从下标1开始
}
sum[1]=p[1];
for(int i=2;i<=n;i++) {
sum[i]=sum[i-1]+p[i];//从下标1开始
}
int t=Sz(p,m);
System.out.println(t);
}
}
private static int Sz(int[] p, int[][] m) {
// TODO Auto-generated method stub
int n1=p.length-1;
for(int i=1;i<=n1;i++) {m[i][i]=0;}
for(int r=2;r<=n1;r++) {//第r行对角线,主对角线作为第一行,向右上方递推
for(int i=1;i<=n1-r+1;i++) {//每条对角线从第1行到第n-r+1行
int j=r-1+i;//存在逻辑关系:j-i=r-1,由方阵性质:每条对角线上有j-i相同
m[i][j]=m[i][i]+m[i+1][j]+sum[j]-sum[i-1];//初始化每个m[i][j]看作最小,sum[j]-sum[i-1]是指最后得到两堆时还需花费初始第i堆累加至第j堆
for(int k=i+1;k<j;k++) {
int f=m[i][k]+m[k+1][j]+sum[j]-sum[i-1];
if(f<m[i][j]) {//找到更小的赋给m[i][j]
m[i][j]=f;
}
}
}
}
return m[1][n1];
}
}