1. 题目
给定一个由n行数字组成的数字三角形,如下图所示:
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大(每一步只能从一个数走到下一层上和它最近的左边的数或者右边的数)。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大(每一步只能从一个数走到下一层上和它最近的左边的数或者右边的数)。
输入:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
第一行为三角形总行数n
输出:
30
2.子问题划分
假设n=3,则要想知道第一行元素到第三行元素的最大路程,则需要先知道第二行两个元素到第三行的最大路程。由此我们可以设m[i,j]:从第i,j个元素出发到底层的最大路径
3.递推方程
初值:m[n,j] = triangle[n,j] , j=1,2,...,n
//即最底层到最底层的路径为三角形矩阵中的值
递推方程: m[i,j] = max{m[i+1,j], m[i+1,j+1]} + triangle[i,j]
//m[i+1,j] 是离i,j号元素最近的左边的数,m[i+1,j+1] 是离i,j号元素最近的右边的数,
4.代码
static int n,
triangle[][];
static int maxPath(){
int m[][] = new int[n+1][n+1];
//赋初始值
for(int j=1;j<=n;j++){
m[n][j] = triangle[n][j];
}
for(int i=n-1;i>=1;i--){
for(int j=1;j<=i;j++){
m[i][j] = Math.max(m[i+1][j], m[i+1][j+1]) + triangle[i][j];
}
}
return m[1][1];
}
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
triangle = new int[n+1][n+1];
String str[];
//从控制台读入三角形里的数
for(int i=1;i<=n;i++){
str = br.readLine().split(" ");
for(int j=1;j<=i;j++){
triangle[i][j] = Integer.parseInt(str[j-1]);
}
}
System.out.println(maxPath());
}