[Dynamic programming] - number tower (java version, super detailed diagram)

  Personal Homepage: Personal Homepage
​ Series Columns: Data Structures and Algorithms

number tower problem

[Problem description] Starting from the top level of the number tower, you can choose to go left or right at each node , and go straight to the bottom. It is required to find a path that maximizes the sum of the values ​​on the path .
 

 

 

Problem analysis: To find the maximum value and the maximum value on the path , you only need to find the largest number of towers on the left (12) and right (15) of " 8" .

  • Left (12)
  • To ask for the maximum value on the path of the number tower of 12, you only need to find out who is the largest number tower on the left (3) and right (9) of "12 "
  • To ask for the maximum value on the path of the number tower of 3, you only need to find out who is the largest number tower on the left (8) and right (10) of "3 "
  • To ask for the maximum value on the path of the number tower of 9, you only need to find out who is the largest number tower on the left (10) and right (5) of "9 "
  • ...................................................... ......wait wait wait
  • Right (15)
  • To ask for the maximum value on the path of the number tower of 15, you only need to find out who is the largest number tower on the left (9) and right (6) of "15 "
  • To ask for the maximum value on the path of the number tower of 9, you only need to find out who is the largest number tower on the left (10) and right (5) of "9 "
  • To ask for the maximum value on the path of the number tower of 6, you only need to find out who is the largest number tower on the left (5) and right (12) of "6 "
  • ...................................................... ......wait wait wait
  • It can be seen that the basic idea of ​​the dynamic programming algorithm is similar to the divide and conquer method . It also decomposes the problem to be solved into several sub-problems (stages) , and solves the sub-stages in sequence. Solving provides useful information. When solving any sub-problem, various possible local solutions are listed, those local solutions that are likely to be optimal are retained by decision-making, and other local solutions are discarded. Solve each sub-problem in turn, and the last sub-problem is the solution to the initial problem.

Our problem-solving idea: first find the sub-problem , that is, first find the maximum value of the bottom layer, for example: first find the maximum value of the path of each number in the fourth layer (here because the fourth layer is the bottom layer, that is, itself) , and then the third layer finds the maximum value of each number path in the third layer by judging the left and right sides of the layer below itself (the fourth layer, such as 16 (left) and 4 (right) below 8), which is greater , a bit abstract, give you a picture to explain:

 

 Let's start from the bottom, because the 4th layer is the bottom layer, so the maximum value is itself, which is the initialization in the figure .

16 4 18 10 9 respectively. Looking at the third layer, the left side of 8 is 16 and 4 respectively. Because 16 is the largest , the maximum value of the path of the number tower with 8 as the root is 24. Similarly, the maximum value of the path of the number tower with 10 as the root is 28. The maximum value of the number tower path rooted at 5 is 23, and the maximum value of the number tower path rooted at 12 is 22. By analogy, the sum of the values ​​on the path is found to be a maximum of 60

Start writing code:

First, we use a two-dimensional array to store the number of towers

 


public class TTT {
    public static void main(String[] args) {
            int[][] d=new int[5][5];
            d[0][0]=8;
            d[1][0]=12;
            d[2][0]=3;
            d[3][0]=8;
            d[4][0]=16;
            d[1][1]=15;
            d[2][1]=9;
            d[3][1]=10;
            d[4][1]=4;
            d[2][2]=6;
            d[3][2]=5;
            d[4][2]=18;
            d[3][3]=12;
            d[4][3]=10;
            d[4][4]=9;
            //遍历二维数组
            int cnt=0;
            for (int[] row : d) {
                    cnt=0;
                    for (int data : row) {
                            cnt++;

                            System.out.printf("%d\t", data);
                            //当输出的数字等于数组长度时,换行
                            if (cnt==d.length){
                                    System.out.println();
                            }


                    }
            }

    }
}

 

 analyze:

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

Indicates that the two numbers below this number are added to itself to take the largest one.

E.g:

 Take 8 as an example

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

d[i][j]=Math.max(16+8,4+8)=24

 

 

        for (int i= d.length-2;i>0;i--){
            for (int j=0;j<=i;j++){
                d[i][j]=Math.max(d[i+1][j]+d[i][j],d[i+1][j+1]+d[i][j]);
//                System.out.println(d[i][j]);
            }
        }
        System.out.println(Math.max(d[1][0] + d[0][0], d[1][1] + d[0][0]));

 Because in the beginning we started with 8 on the penultimate level

So at the beginning

i=d.leng-2 (that is, the row number position index of 8)

j=0 (that is, the column number position index of 8)

Full code: 

 

public class CountingTower {
    public static void main(String[] args) {
        int[][] d=new int[5][5];
        d[0][0]=8;
        d[1][0]=12;
        d[2][0]=3;
        d[3][0]=8;
        d[4][0]=16;
        d[1][1]=15;
        d[2][1]=9;
        d[3][1]=10;
        d[4][1]=4;
        d[2][2]=6;
        d[3][2]=5;
        d[4][2]=18;
        d[3][3]=12;
        d[4][3]=10;
        d[4][4]=9;
        //遍历二维数组
        int cnt=0;
        for (int[] row : d) {
            cnt=0;
            for (int data : row) {
                cnt++;

                System.out.printf("%d\t", data);
                //当输出的数字等于数组长度时,换行
                if (cnt==d.length){
                    System.out.println();
                }


            }
        }


        for (int i= d.length-2;i>0;i--){
            for (int j=0;j<=i;j++){
                d[i][j]=Math.max(d[i+1][j]+d[i][j],d[i+1][j+1]+d[i][j]);
//                System.out.println(d[i][j]);
            }
        }
        System.out.println(Math.max(d[1][0] + d[0][0], d[1][1] + d[0][0]));


    }

}

 

Guess you like

Origin blog.csdn.net/Javascript_tsj/article/details/124402913