1. 程式人生 > >動態規劃演算法之數塔問題

動態規劃演算法之數塔問題

一、問題描述

從數塔頂層出發,每個結點可以選擇向左走或向右走,要求一直走到塔底,使得走過的路徑上的數值和最大。


如上圖所示的數塔,最大路徑和為86,經過的路徑從塔頂到塔底為13,8,26,15,24。

二、問題分析

動態規劃函式為:

resultTower[i][j] = tower[i][j] + Math.max(tower[i + 1][j],tower[i + 1][j + 1]);

邊界值resultTower[heigh - 1][j] = tower[heigh - 1][j];

三、演算法程式碼

public int dataTower(int tower[][]){
		int heigh = tower.length;//數塔高度
		int len = tower[heigh - 1].length;//數塔底部寬度
		int [][] resultTower = new int[heigh][len];//結果數塔,存放路徑數值和
		int [][] path = new int[heigh][len];//計算結果數塔生成路徑
		
		//初始化結果數塔
		for(int i = 0; i < len; i++){
			resultTower[heigh - 1][i] = tower[heigh - 1][i];
		}
		
		//開始計算結果數塔及路徑
		for(int i = heigh - 2; i >= 0; i--){
			for(int j = 0; j <= i; j++){
				if(resultTower[i + 1][j] > resultTower[i + 1][j + 1]){
					resultTower[i][j] = tower[i][j] + resultTower[i + 1][j];
					path[i][j] = j; 
				}else{
					resultTower[i][j] = tower[i][j] + resultTower[i + 1][j + 1]; 
					path[i][j] = j + 1;
				}
			}
		}
		
		//列印路徑
		System.out.println("最大數值和為" + resultTower[0][0] + "\n最大數值和路徑:");
		System.out.println("第0層數值:" + tower[0][0]);
		int j = path[0][0];
		for(int i = 1; i <= heigh - 1; i++){
			System.out.println("第" + i + "層數值:" + tower[i][j]);
			j = path[i][j];
		}
		System.out.println();
		
		return resultTower[0][0];
	}
四、完整測試程式碼
public class Solution {
	
	public static void main(String [] args){
		int [][] tower = {{13},{11,8},{12,7,26},{6,14,15,8},{12,7,13,24,11}};
		int result = dataTower(tower);
	}
	public static int dataTower(int tower[][]){
		int heigh = tower.length;//數塔高度
		int len = tower[heigh - 1].length;//數塔底部寬度
		int [][] resultTower = new int[heigh][len];//結果數塔,存放路徑數值和
		int [][] path = new int[heigh][len];//計算結果數塔生成路徑
		
		//初始化結果數塔
		for(int i = 0; i < len; i++){
			resultTower[heigh - 1][i] = tower[heigh - 1][i];
		}
		
		//開始計算結果數塔及路徑
		for(int i = heigh - 2; i >= 0; i--){
			for(int j = 0; j <= i; j++){
				if(resultTower[i + 1][j] > resultTower[i + 1][j + 1]){
					resultTower[i][j] = tower[i][j] + resultTower[i + 1][j];
					path[i][j] = j; 
				}else{
					resultTower[i][j] = tower[i][j] + resultTower[i + 1][j + 1]; 
					path[i][j] = j + 1;
				}
			}
		}
		
		//列印路徑
		System.out.println("最大數值和為" + resultTower[0][0] + "\n最大數值和路徑:");
		System.out.println("第0層數值:" + tower[0][0]);
		int j = path[0][0];
		for(int i = 1; i <= heigh - 1; i++){
			System.out.println("第" + i + "層數值:" + tower[i][j]);
			j = path[i][j];
		}
		System.out.println();
		
		return resultTower[0][0];
	}
}
五、執行結果
最大數值和為86
最大數值和路徑:
第0層數值:13
第1層數值:8
第2層數值:26
第3層數值:15
第4層數值:24