7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
如上圖所示,從一個數字三角形的頂部走到底部有不少條不一樣的路徑,規則是隻能從當前節點走到下一層相鄰的節點,即下一層的左邊或右邊。例如第三行第二個數字「1」只能走到第四行的第二個數字「7」與第三個數字「4」。
請尋找最佳一條路徑,使得這條路徑上節點的數字總和最大。java
輸入包含多組。每組數據的第一行包含一個正整數n(1≤n≤100),表明三角形的層數。
緊接着有n行數字,第i(1≤i≤n)行包含i個天然數。算法
對應每組數據,輸出最大的和。數組
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
30
將示例的輸入轉換成二維數組。如圖1所示。
圖1 數據流動圖
根據意思和圖1分分析,本題可使用動態規劃解決。設有待求最大值的矩陣matrix,它有n行,第i行最多i列,每一個元素的值都是正數。第i(從1開始計算)行第j(從1開始計算)列對應到matrix的位置爲matrix[i-1][j-1]。
第一列,它的第一行只有一個元素,它的最大值就是其自身,對於其它行,第一列的最大值等於它上一個元素的最大值加上當前值。對象線上的元素,除第一個元素外,其它元素的最大值等於它的左上角元素的最大值和當前值的和。最後對矩陣中的其它元素,其最大值等於左上角元素的最大值和上方元素的最大兩都取較大的,再和當前值相加。對於matrix[i][j]有遞推方程測試
matrix[i][j]=⎧⎩⎨⎪⎪⎪⎪⎪⎪matrix[i][j]matrix[i−1][j]+matrix[i][j](matrix[i−1][j−1]+matrix[i][j]max{matrix[i−1][j−1],matrix[i−1][j]}+matrix[i][j]i=0andj=0i>0andj=0i=j>0i>j>0spa
最後,要求出matrix中的最大值只要遍歷最後一列,它們中的最大值就是所求的matrix的最大值。code
import java.util.Scanner; /** * Declaration: All Rights Reserved !!! */ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt")); while (scanner.hasNext()) { int n = scanner.nextInt(); int[][] matrix = new int[n][]; for (int i = 1; i <= n; i++) { matrix[i - 1] = new int[i]; for (int j = 0; j < i; j++) { matrix[i - 1][j] = scanner.nextInt(); } } System.out.println(maxSum(matrix)); } scanner.close(); } /** * 找最大值 * * @param matrix 正數對角矩陣 * @return 最大值 */ private static int maxSum(int[][] matrix) { int row = matrix.length; // 第一個元素不用求最大值 // 求第一列和對象線最大值 for (int i = 1; i < row; i++) { matrix[i][0] += matrix[i - 1][0]; matrix[i][i] += matrix[i - 1][i - 1]; } // 最其它元素的最大值 for (int i = 2; i < row; i++) { for (int j = 1; j < i; j++) { matrix[i][j] += Math.max(matrix[i - 1][j - 1], matrix[i - 1][j]); } } int max = Integer.MIN_VALUE; // 找最大值 for (int i = 0; i < row; i++) { if (max < matrix[row - 1][i]) { max = matrix[row - 1][i]; } } return max; } }