目录
变种数塔问题
给定一个数塔,从数塔的顶层出发,在每个结点可以选择向右或者向下走,一直走到最底层,要求找到一条路径,使得该路径上的数值和最大。以下图数塔为例。(最后一层不能向右走)
经典数塔问题是上一层到下一层的左或者右,这里是右或下
不难看出最大值为13
自上而下dp
package Pta;
import java.util.*;
//3
//2
//4 5
//1 2 3
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int len = sc.nextInt();
int[][] dp = new int[len][len];
int[][] arr = new int[len][len];
for (int i = 0; i < len; i++) {
for (int j = 0; j <= i; j++) {
arr[i][j] = sc.nextInt();
}
}
dp[0][0]=arr[0][0];
for(int i=1;i<len;i++){
dp[i][0]=arr[i][0]+arr[i-1][0];
}
for(int i=1;i<len;i++){
for(int j=i;j>=1;j--){
dp[i][j]=arr[i][j]+Math.max(dp[i][j-1],dp[i-1][j]);
}
}
System.out.println(Arrays.deepToString(dp));
int max=0;
for(int i=0;i<len;i++){
if(max<dp[2][i]){
max=dp[2][i];
}
}
System.out.println(max);
}
}
优化:自下而上dp(省略求最大dp过程)
package Pta;
import java.util.*;
//3
//2
//4 5
//1 2 3
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int len = sc.nextInt();
int[][] dp = new int[len][len];
int[][] arr = new int[len][len];
for (int i = 0; i < len; i++) {
for (int j = 0; j <= i; j++) {
arr[i][j] = sc.nextInt();
}
}
for (int i = 0; i < len; i++) {
dp[len - 1][i] = arr[len - 1][i];
}
//System.out.println(Arrays.deepToString(dp));
for (int i = len - 2; i >= 0; i--) {
for (int j = i; j>=0; j--) {
dp[i][j] = arr[i][j] + Math.max(dp[i][j+1], dp[i+1][j]);
}
}
System.out.println(Arrays.deepToString(dp));
System.out.println(dp[0][0]);
}
}