题目:
解法一:递归
import java.util.Arrays;
import java.util.Scanner;
public class Main {
/*
* 思路:
* 通过深度优先遍历,从上往下进行查找
* 每次将当前点作为起点,寻找最长路径。该点+该点往后的最长路径
测试数据:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
* */
static int n; //行数
static int[][] g; //存储三角形
static int ans; //存放最大值
public static void main(String[] args) {
//(1)输入相关数据
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
g = new int[n][];//创建行
for(int i=0;i<n;i++) {
g[i] = new int[i+1];//针对每一行初始化
for(int j=0;j<=i;j++) {
g[i][j]=sc.nextInt();
}
}
//(2)进行深度优先遍历,获取最大值
ans = dfs(0,0);
System.out.println(ans);
}
//递归
private static int dfs(int x, int y) {
if(x==n-1) {//遍历到最后一行,以该点为起点,最长路径只能是其本身
return g[x][y];
}
return g[x][y]+Math.max(dfs(x+1,y),dfs(x+1,y+1));//当前行x的元素g[x][y] + 以该点为起点的最长路径
}
}
解法二:记忆型递归(提高效率,避免重复计算)
import java.util.Arrays;
import java.util.Scanner;
public class Main {
/*
* 思路:
* 通过深度优先遍历,从上往下进行查找
* 每次将当前点作为起点,寻找最长路径。该点+该点往后的最长路径
测试数据:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
* */
static int n; //行数
static int[][] g; //存储三角形
static int ans; //存放最大值
static int[][] rem;//rem[x][y],记忆以点(x,y)作为起点的最长路径
public static void main(String[] args) {
//(1)输入相关数据
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
g = new int[n][];//创建行
for(int i=0;i<n;i++) {
g[i] = new int[i+1];//针对每一行初始化
for(int j=0;j<=i;j++) {
g[i][j]=sc.nextInt();
}
}
rem = new int[n][n];
//(2)进行深度优先遍历,获取最大值
ans = dfs(0,0);
System.out.println(ans);
}
//递归
private static int dfs(int x, int y) {
if(x==n-1) {//遍历到最后一行,以该点为起点,最长路径只能是其本身
return g[x][y];
}
//(1)计算前先查找是否已存在
if(rem[x][y]>0) return rem[x][y];
int p = g[x][y]+Math.max(dfs(x+1,y),dfs(x+1,y+1));//当前行x的元素g[x][y] + 以该点为起点的最长路径
//(2)计算后,将结果存到rem
rem[x][y]=p;
return p;
}
}
解法三:动态规划(从底向上查找)使用二维dp数组
import java.util.Arrays;
import java.util.Scanner;
public class Main {
/*
* 思路:
*通过动态规划,从底向上进行查找(先确定被依赖点的最大路径)。可知从上层出发的点的最大路径 都依赖于 下一层的大小,故先确定最底层
测试数据:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
* */
static int n; //行数
static int[][] g; //存储三角形
static int[][] dp;//dp[i][j]从点(i,j)出发的最长路径
public static void main(String[] args) {
//(1)输入相关数据
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
g = new int[n][];//创建行
for(int i=0;i<n;i++) {
g[i] = new int[i+1];//针对每一行初始化
for(int j=0;j<=i;j++) {
g[i][j]=sc.nextInt();
}
}
//(2)初始化dp的最后一行,以该行上的点作为起点的最大路径都是其本身
dp = new int[n][n];
for(int i=0;i<n;i++) {
dp[n-1][i] = g[n-1][i];
}
for(int i=n-2;i>=0;i--) {//依次确定每一行
for(int j=0;j<=i;j++) {
dp[i][j]=g[i][j]+Math.max(dp[i+1][j], dp[i+1][j+1]);//以(i,j)作为起点的最大路径
}
}
//(2)进行深度优先遍历,获取最大值
System.out.println(dp[0][0]);
}
}
解法四:使用一维dp数组。初始化为最后一行的值,每次更新该数组的值,最后dp[0]为最大路径。(节约空间)
dp中存放当前行中的点 为起点的最大路径
import java.util.Arrays;
import java.util.Scanner;
public class Main {
/*
* 思路:
*通过动态规划,从底向上进行查找(先确定被依赖点的最大路径)。可知从上层出发的点的最大路径 都依赖于 下一层的大小,故先确定最底层
测试数据:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
* */
static int n; //行数
static int[][] g; //存储三角形
static int[] dp;//dp[i][j]从点(i,j)出发的最长路径
public static void main(String[] args) {
//(1)输入相关数据
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
g = new int[n][];//创建行
for(int i=0;i<n;i++) {
g[i] = new int[i+1];//针对每一行初始化
for(int j=0;j<=i;j++) {
g[i][j]=sc.nextInt();
}
}
//(2)初始化dp的最后一行,以该行上的点作为起点的最大路径都是其本身
dp = new int[n];
for(int i=0;i<n;i++) {
dp[i] = g[n-1][i];
}
for(int i=n-2;i>=0;i--) {//依次确定每一行
for(int j=0;j<=i;j++) {
dp[j]=g[i][j]+Math.max(dp[j], dp[j+1]);//以(i,j)作为起点的最大路径
}
}
//(2)进行深度优先遍历,获取最大值
System.out.println(dp[0]);
}
}