算法學習——動態規劃之點數值三角形的最小路徑
阿新 • • 發佈:2018-11-13
頂點 結果 等於 system.in lag -- 技術分享 4行 info
算法描述
在一個n行的點數值三角形中,尋找從頂點開始每一步可沿著左斜或者右斜向下直到到達底端,使得每個點上的數值之和為最小
右圖為一個4行的點數值三角形
算法思路
接收用戶輸入行數n
使用一個二維數組
a[n+1][n+1]
來存放各個點上的數值,數值可以由用戶輸入或者是隨機生成定義一個二維數組(用來存放方向)
direction[n+1][n+1]
,存放1或0,1代表右
,0代表左
定義一個二維數組
b[n+1][n+1]
表示到底端的數值之和以上圖4行的點數值三角形為例
b[4][1]=47
b[4][2]=93
b[3][1]=43
這裏b[3][1]是可以等於47,也可以等於93,但題目要求的是最小,所以這裏取小的值
b[3][1]其實是由逆推得到的,具體看下面
b[n+1][n+1]的遞推關系
初始值
從最後一行開始
b[n][i]=a[n][i]
i遍歷完最後一行的所有元素遞推關系
b[n][i]=Math.min(b[n+1][i],b[n+1][i+1]) 取最小值
算法實現
System.out.println("輸入數字三角形的行數n:"); Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); scanner.close(); int[][] a= new int[n+1][n+1]; //隨機賦值數字三角形 for(int i=1;i<n+1;i++){ for(int j =1;j<=i;j++){ a[i][j] = (int) (Math.random()*100); } } //輸出數字三角形 for(int i=1;i<n+1;i++){ for(int j =1;j<=i;j++){ System.out.print(a[i][j]+" "); } System.out.println(""); } int[][] b = new int[n+1][n+1]; int[][] direction = new int[n+1][n+1];//0是左,1是右 //最後一行的長度為其本身 for(int i=1;i<n+1;i++){ b[n][i] = a[n][i]; } //關鍵逆推代碼 for(int i=n-1;i>=1;i--){ for(int j=1;j<=i;j++){ if(b[i+1][j+1]<b[i+1][j]){ b[i][j]=a[i][j] + b[i+1][j+1]; direction[i][j]=1;//右邊的數值較大,則記錄方向為右 }else{ b[i][j]=a[i][j] + b[i+1][j]; direction[i][j]=0;//左邊的數值較大,則記錄方向為左 } } } System.out.println("最小路徑和為"+b[1][1]); int flag = 1; int j=1; //循壞結束 while(flag!=n){ System.out.print(a[flag][j]); if(direction[flag][j]==1){ System.out.print("->向右"); flag++; j++; }else{ System.out.print("->向左"); flag++; } } System.out.print("->"+a[flag][j]); }
結果
算法學習——動態規劃之點數值三角形的最小路徑