R Language Programming: One of Ali Push-Pen Test
subject
Muzhe is a picker in a bird warehouse, but he has a very strange habit.Each pickup is lighter than the one previously picked. You can get one dollar each time you pick it up. Muzhe wants to know how much money you can make in this way.
32 34 7 33 21 2
13 12 3 11 26 36
16 30 22 1 24 14
20 23 25 5 19 29
27 15 9 17 31 4
6 18 8 10 35 28
Muzhe can start picking from a shelf in the warehouse. The next step is to go up or down, of course, to the left or right, but it must reduce the weight of the next item before it can be picked up.In the warehouse above, a pickable path is 25-22-3.Of course, 30-23-20-16-13-12-3 has more to pick up.This is also the path to making the most money.
Requirement
Enter the number of rows, columns, and data matrix to output the maximum amount of money earned.
Example:
Input:
6 6
32 34 7 33 21 2
13 12 3 11 26 36
16 30 22 1 24 14
20 23 25 5 19 29
27 15 9 17 31 4
6 18 8 10 35 28
Output:
7
Solving process:
I have come up with two ideas to design the program, the shortcomings are welcome to point out, thank you!
Method 1: Solving Violence
This means that the solution of violence is to find the maximum number of steps that can be taken by each element on the shelf. There is no need to store the coordinates of each step. As long as the address of step k+1 exists at all addresses based on step k, it means that step k+1 can be reached until the condition is not met, and K is the maximum number of steps.
Function:
Parameter description:
n.row: Number of rows representing the original weight matrix
n.col: Number of columns representing the original weight matrix
start.i: The x-coordinate representing the initial cargo
start.j: Represents the ordinate coordinates of the initial cargo
M: Represents the initial weight matrix
Num_Step <- function(n.row, n.col, start.i, start.j, M){
i <- start.i
j <- start.j
s <- 1
next_step <- list(c(i,j))
repeat{
index <- list()
for(k in 1:length(next_step)){
i <- next_step[[k]][1]
j <- next_step[[k]][2]
if(i==1){
next_up <- NA
}else if(M[i,j]>M[i-1,j]){
next_up <- c(i-1,j)
}else{
next_up <- NA
}
if(i==n.row){
next_down <- NA
}else if(M[i,j]>M[i+1,j]){
next_down <- c(i+1,j)
}else{
next_down <- NA
}
if(j==1){
next_left <- NA
}else if(M[i,j]>M[i,j-1]){
next_left <- c(i,j-1)
}else{
next_left <- NA
}
if(j==n.col){
next_right <- NA
}else if(M[i,j]>M[i,j+1]){
next_right <- c(i,j+1)
}else{
next_right <- NA
}
next_id <- list(next_up, next_down, next_left, next_right,NA)
next_id <- next_id[-which(is.na(next_id))]
index <- c(index, next_id)
}
if(length(index)==0){
break
}
next_step <- index
s <- s+1
}
return(s)
}
test result
## Calculate the maximum return for all elements as starting points
BL_step <- function(n.row, n.col, M){
price <- matrix(NA, n.row, n.col)
for(start.i in 1:n.row){
for(start.j in 1:n.col){
price[start.i,start.j] <- Num_Step(n.row, n.col, start.i, start.j, M)
}
}
return(price)
}
## Take the shelf given in the title as an example:
M <-matrix(c(32, 34, 7, 33, 21, 2, 13, 12, 3, 11, 26, 36, 16, 30, 22, 1, 24, 14, 20, 23, 25, 5, 19, 29, 27, 15, 9, 17, 31, 4, 6, 18, 8, 10, 35, 28),6,byrow = T)
n.row <- nrow(M)
print(paste("n.row",n.row, sep = "="))
n.row = 6
n.col <- ncol(M)
print(paste("n.col",n.col, sep = "="))
n.col = 6
Output Income Matrix
BL_step(n.row, n.col, M)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 4 5 2 3 2 1
[2,] 3 2 1 2 5 6
[3,] 4 7 2 1 4 1
[4,] 5 6 7 2 3 4
[5,] 6 3 2 3 4 1
[6,] 1 4 1 2 5 2
Method 2: Dynamic planning
Explanation: Using the idea of dynamic programming, starting from the element with the minimum maximum number of steps, there must be an element with step s-1 at the top, bottom, left and right of the element with the maximum number of steps.
Algorithmic steps:
1. Make P a step matrix of the same dimension as the initial shelf weight matrix (the initial elements are all 0)
2.s=1, i.e. the maximum step is 1 to start
3. If an element in a matrix satisfies both upper and lower left and right positions that are greater than that element, then the maximum step of that element is 1
4. From s=2 onwards, take the unassigned elements in the matrix (that is, the elements = 0) and make a judgment one by one
5. Decision 1: There is at least one element with a maximum step length of (s-1) in the top, bottom, left and right elements of the element
6.Judgment Condition 2: If Judgment Condition 1 is satisfied, then all elements except (s-1) elements that are smaller than this element are assigned values, that is, they can only be entered and cannot go in any other direction; or if the other positions are larger than this element, then this element is (s+1) step element.
7. Repeat steps 3-6 until the matrix has all elements assigned.
Functions and results
Parameter description:
n.row: The number of rows of the initial matrix
n.col: Number of columns of the initial matrix
M: Initial shelf weight matrix
LP_Step <- function(n.row, n.col, M){
p <- matrix(0, n.row, n.col)
s=1
repeat{
step_id <- which(p==0, arr.ind = T)
temp_step <- c()
for(k in 1:nrow(step_id)){
i <- step_id[k,1]
j <- step_id[k,2]
if(i==1){
up <- NA
}else{
up <- c(i-1, j)
}
if(i==n.row){
down <- NA
}else{
down <- c(i+1, j)
}
if(j==1){
left <- NA
}else{
left <- c(i, j-1)
}
if(j==n.col){
right <- NA
}else{
right <- c(i, j+1)
}
round_id <- rbind(up, down, left, right,NA)
round_id <- round_id[-which(is.na(round_id), arr.ind = T)[,1],]
round_value <- M[round_id]
round_p <- p[round_id]
id <- which(round_value < M[i,j])
juge_last <- which(round_p==(s-1))
if(length(juge_last)>0){
if(s==1){
if(M[i,j] <= min(round_value)){
temp_step <- rbind(temp_step,c(i,j))
}
}else if(all(round_p[id]!=0, na.rm = T)){
temp_step <- rbind(temp_step,c(i,j))
}
}
}
p[temp_step] <- s
if(length(which(p==0))==0){
break
}
s=s+1
}
return(p)
}
M <-matrix(c(32, 34, 7, 33, 21, 2, 13, 12, 3, 11, 26, 36, 16, 30, 22, 1, 24, 14, 20, 23, 25, 5, 19, 29, 27, 15, 9, 17, 31, 4, 6, 18, 8, 10, 35, 28),6,byrow = T)
n.row <- nrow(M)
n.col <- ncol(M)
LP_Step(n.row, n.col, M)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 4 5 2 3 2 1
[2,] 3 2 1 2 5 6
[3,] 4 7 2 1 4 1
[4,] 5 6 7 2 3 4
[5,] 6 3 2 3 4 1
[6,] 1 4 1 2 5 2