从上向下走,这种方法容易想到,但是容易出错,出错的地方主要是因为给定的数字中存在负数 ,初始化的dp数组全部为0,0和负数相比是0大,容易当数组元素存在负数或者全部负数的时候会导致结果的不正确。
这就需要对dp数组进行初始化,初始化成比给定的数据更小的数字即可。
第一行的数字不需要更新,第二行开始。第i行的第j列数字可能会被i-1行的j列和j-1列更新,更新的时候选择一个更大值。
存在j-1的问题,数组需要从1开始,避免越界,同时第i-1列不存在第i列,也需要将数组开的大一些,同时对于一些不存在的位置需要进行初始化!
package dp;
import java.util.Scanner;
public class 数字三角形 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int N=510;
Scanner sc= new Scanner(System.in);
int n=sc.nextInt();
int a[][]=new int [N][N];
int dp[][]=new int [N][N];
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
a[i][j]=sc.nextInt();
}
}
for(int i=0;i<=n;i++){
for(int j=0;j<=n+1;j++){
dp[i][j]=Integer.MIN_VALUE;
}
}
dp[1][1]=a[1][1];
for(int i=2;i<=n;i++){
for(int j=1;j<=i;j++){
dp[i][j]=a[i][j]+Math.max(dp[i-1][j], dp[i-1][j-1]);
}
}
int res=0;
for(int j=1;j<=n;j++){
res=Math.max(res, dp[n][j]);
}
System.out.println(res);
}
}
首先题目要求的求解从上层走到底层的路径之和,每一次只能向下或者向右下方走。
有两种走法,可以是从上到下,也可以是从下到上。
从下到上的方法比较简单,而且最后一行也不需要进行更新,从第n-1开始循环,一直循环到第1行为止。然后一个数字的更新取决于两个数字,分别是他下面的那个数字和右下方的数字有关。
状态转移方程就是a[i][j]+=max(a[i+1][j],a[i+1][j+1]).
因为是从第n-1行开始的,其后面的每一行的个数比前面的一行多1,在第i行循环i列的时候,第i+1行的i+1列也存在。
package dp;
import java.util.Scanner;
public class 数字三角形2 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int N=510;
Scanner sc= new Scanner(System.in);
int n=sc.nextInt();
int a[][]=new int [N][N];
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
a[i][j]=sc.nextInt();
}
}
for(int i=n-1;i>=1;i--){
for(int j=1;j<=i;j++){
a[i][j]+=Math.max(a[i+1][j], a[i+1][j+1]);
}
}
System.out.println(a[1][1]);
}
}