算法學習——動態規劃之點數值三角形的最小路徑

算法描述

在一個n行的點數值三角形中,尋找從頂點開始每一步可沿着左斜或者右斜向下直到到達底端,使得每一個點上的數值之和爲最小算法

右圖爲一個4行的點數值三角形
數組

算法思路

  1. 接收用戶輸入行數ndom

  2. 使用一個二維數組a[n+1][n+1]來存放各個點上的數值,數值能夠由用戶輸入或者是隨機生成code

  3. 定義一個二維數組(用來存放方向)direction[n+1][n+1],存放1或0,1表明右0表明左blog

  4. 定義一個二維數組b[n+1][n+1] 表示到底端的數值之和io

    以上圖4行的點數值三角形爲例遍歷

    b[4][1]=47 b[4][2]=93im

    b[3][1]=43d3

    這裏b[3][1]是能夠等於47,也能夠等於93,但題目要求的是最小,因此這裏取小的值next

    b[3][1]實際上是由逆推獲得的,具體看下面

  5. 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]);

}

結果

相關文章
相關標籤/搜索