在一個n行的點數值三角形中,尋找從頂點開始每一步可沿着左斜或者右斜向下直到到達底端,使得每一個點上的數值之和爲最小算法
右圖爲一個4行的點數值三角形
數組
接收用戶輸入行數ndom
使用一個二維數組a[n+1][n+1]
來存放各個點上的數值,數值能夠由用戶輸入或者是隨機生成code
定義一個二維數組(用來存放方向)direction[n+1][n+1]
,存放1或0,1表明右
,0表明左
blog
定義一個二維數組b[n+1][n+1]
表示到底端的數值之和io
以上圖4行的點數值三角形爲例遍歷
b[4][1]=47
b[4][2]=93
im
b[3][1]=43
d3
這裏b[3][1]是能夠等於47,也能夠等於93,但題目要求的是最小,因此這裏取小的值next
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]); }