An understanding of the method for finding the maximum sum of submatrixes in dynamic programming given on the Internet

I saw a method on the Internet to find the maximum sum of submatrixes using dynamic programming (code links are below)

Code link: https://blog.csdn.net/wy250229163/article/details/52819403

Here is my understanding of this code:

1. First, a global variable two-dimensional array num is defined. As for why there is an extra row and column, and why the row and column are not 100 and 100, this question will be explained later

 

2. Then n is the number of test samples, there are several sets of data, and the while loop is only a few times, this is nothing to say

3. Then he initializes all elements in the array to 0 through the memset function

4. Then I think this code is written very cleverly. The num array is not simply used to store the data of this two-dimensional matrix. It can only be said that the data in the two-dimensional matrix is ​​temporarily stored and temporarily stored in it. After that, immediately for each element num[i][j] of each row, find the sum of the first i items in this column (which is equivalent to finding the sum of the first i items in units of columns).

That is to say, the data stored in the current two-dimensional matrix is ​​as follows: (here takes a 5*4 matrix as an example)

(Note that both i and j in the code are traversed from 1, so the edges of the upper left corner are all 0)

0

0

0

0

0

0

the first element of the first column

the first element of the second column

……….

……….

0

The first two elements of the first column and

The sum of the first two elements in the second column

……….

……….

0

The first three elements of the first column and

The first three elements of the second column and

……….

……….

0

The first four elements of the first column and

The first four elements of the second column and

……….

……….

0

The first five elements of the first column and

……….

……….

……….

 

         The reason why there is a half-circle of 0s on the outermost side is because the method of accumulating num[i][j]+=num[i-1][j] is used to calculate the sum of the first i items on each column in the code , then for the elements of the first row, if there is no 0 in the outermost circle, i-1 will make the subscript of the array out of bounds. It is necessary to discuss the situation and divide it into the first row and the non-first row for accumulation, which is a bit It is troublesome, so a half circle of 0 is added to ensure that no matter which line is used, the sum of the first n items is calculated in the same way, which is why there is an operation of 101 in step 1 and all initialized to 0 in step 3

5. The next step is to find the largest submatrix

The idea of ​​traversing a submatrix is ​​roughly as follows: (We take the submatrix of a 3*3 matrix as an example)
       

Below I will draw which sub-matrices are traversed during the traversal process, and place the subscripts next to them

When i=1,j=1:

           k=1                                                k=2                                                       k=3

                                                                                            

        

                                                                                              

When i=1,j=2:

             k=1                                    k=2                                                          k=3

                                                                                 

 

                                                              


When i=1, j=3.....(draw another one when i=2, j=2, it will not be drawn later, you can draw it yourself)

…………

When i=2,j=2:

     k=1                                   k=2                                                           k=3

                                                                                   

                                                                   


When i=2,j=3,......(omitted)


illustrate:

         For temp=num[j][k]-num[i-1][k] and tempmax=(tempmax>=0?tempmax:0)+temp, if you don’t look carefully, it seems to be traversed according to the above, temp is the sum of the sub-matrices in the first row of each case, and tempmax is the sum of the sub-matrices in the second row of each case (that is, the result of the previous traversal is accumulated on the basis of the current temp)

         But things are not so simple, this is not a simple accumulation, he adds a (tempmax>=0?tempmax:0)

(1). Let’s first explain why it is compared with 0 (that is, why it is a positive number before adding), just imagine, if tempmax is a negative number, then tempmax, tempmax+temp and temp, the largest must be temp, because we What we want is the largest sub-matrix sum. If you add a negative number, it will only be smaller, not larger, and it is not the maximum value we want, so when tempmax is a negative number, let tempmax=temp directly, with the current value Accumulates based on the temp of the second traversal.

(2). In fact, I didn't think about it carefully when I first read this code. I always feel that if the largest submatrix is ​​in the middle or in the lower right corner, it may not be traversed in some cases.

Now, let's think about this situation carefully. If the largest sub-matrix is ​​in the lower right corner or the middle, that is to say, the elements in the columns to the left of him cannot be used as the elements in the largest sub-matrix, that is, in the accumulation In the process, the elements of the left column that were originally counted in tempmax were "abandoned", which is exactly the situation mentioned in (1). That is, when k traverses to a column in the middle, it is found that the last tempmax does not have The temp of this traversal is large, so that tempmax=temp, and then it is traversed and accumulated based on a temp in the middle, and it may be traversed to the submatrix in the middle or lower right corner.

 

The last max=tempmax>max?tempmax:max, this is nothing to say, normal operation, compare the max obtained in the last traversal with the largest submatrix found in this traversal.

 

This way you can traverse all the submatrix cases without repeating the traversal (much better than my method)

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326509444&siteId=291194637