Title Description:
Given the length, width and height information of n boxes (the order is uncertain, that is, the boxes can be turned over), stack them vertically to find the maximum height that can be stacked.
Requirement: the bottom surface of the upper box shall not exceed the bottom surface of the lower box.
Others: aim at the maximum height that can be obtained without using all boxes.
I. problem solving ideas
#0) still convert data into matrix; The topic design seeks all feasible schemes and considers using DFS programming to solve them.
#1. The three attribute information of the box are arranged and combined into three groups. In each group, the first two attribute elements are used as the bottom edge length and the third attribute element is used as the height.
##Example: arrange and combine the three attribute information "85 35 23" of the box, and the three groups of data are: [85 35 23], [85 23 35], [35 23 85]; So that all three attribute values have the opportunity to be high.
##1.1 store box information with matrix: each line represents a box information, and each box information contains 3 combined data.
#2 when stacking cuboids, each cuboid may be placed at the bottom; Therefore, for n boxes to be stacked, N cycles are required here
##2.1 When a box is stacked at the bottom, each side of it may be as high, that is, there are three placement methods; Therefore, three cycles are required
#3 judgment conditions: used for (pruning) early termination of infeasible scheme
#3.1 the length and width of the bottom surface of the newly stacked cuboids (i.e. the maximum and minimum values of the first two elements in the combined data, which correspond to the length and width of the bottom surface respectively) must be less than the length and width of the bottom surface of the lower cuboids respectively
#4 termination conditions
#Terminate when all boxes have been accessed
#5 finally return to the maximum height that can be obtained
#6 in particular: in order to obtain the maximum height, it is not necessary to stack all boxes, that is, boxes that do not meet the conditions of 3.1 can be discarded.
#6.1 DFS full search can automatically include this situation.
II. Code implementation
# Supplementary escape: # 1. The three attribute information of the box are arranged and combined into three groups. In each group, the first two attribute elements are used as the bottom edge length and the third attribute element is used as the height. ## Example: arrange and combine the three attribute information "85 35 23" of the box, and the three groups of data are: [85 35 23], [85 23 35], [35 23 85]; So that all three attribute values have the opportunity to be high. ## 1.1 store box information with matrix: each line represents a box information, and each box information contains 3 combined data. # 2 when stacking cuboids, each cuboid may be placed at the bottom; Therefore, for n boxes to be stacked, N cycles are required here ##2.1 When a box is stacked at the bottom, each side of it may be as high, that is, there are three placement methods; Therefore, three cycles are required # 3 judgment conditions: used for (pruning) early termination of infeasible scheme # 3.1 the length and width of the bottom surface of the newly stacked cuboids (i.e. the maximum and minimum values of the first two elements in the combined data, which correspond to the length and width of the bottom surface respectively) must be less than the length and width of the bottom surface of the lower cuboids respectively # 4 termination conditions # Terminate when all boxes have been accessed # 5 finally return to the maximum height that can be obtained # 6 in particular: in order to obtain the maximum height, it is not necessary to stack all boxes, that is, boxes that do not meet the conditions of 3.1 can be discarded. # 6.1 DFS full search can automatically include this situation. import collections import math #### data processing def proData(size,subdata): new_data = [] ### Arrange and combine each original data into 3 pieces of data for i in range(size): temp0 = subdata[i][0] temp1 = subdata[i][1] temp2 = subdata[i][2] temp = [[temp0,temp1,temp2],[temp0,temp2,temp1],[temp1,temp2,temp0]] # 3 combined data new_data.append(temp) # Each row represents a box of data return new_data ### DFS processing class Solution: def DFS(self): self.Max_height = [] # The maximum height that can be obtained by storing each scheme #### ######### Each box is placed as the bottom layer, with a total of size for i in range(size): #### Get details node = new_data[i] ### Start with each combination information for j in range(3): start = node[j] ## Set initial information sum = 0 # Cumulative height self.ways = 0 # Initialize the box height that can be obtained by this scheme queue = [] # Store visited boxes; Line number i (each line number represents a box) queue.append(i) # Add the accessed box, i.e. line number I step = 1 # Count, that is, record the number of boxes visited pre_start = [math.inf,math.inf,math.inf] # To compare the length and width of the bottom edge of two adjacent boxes, you need to set a variable to save the information of the box below self.dfs(pre_start,start,sum,step,queue) #### Current bin height self.Max_height.append(self.ways) #### initialization return max(self.Max_height) ## Returns the maximum height in all scenarios def dfs(self,pre_start,start,sum,step,queue): ### 1. Judge whether the stacking conditions are met pre_infor = pre_start[0:2] # The first two elements are the length and width of the bottom edge, and the third element is the height cur_infro = start[0:2] if max(cur_infro)>max(pre_infor) or min(cur_infro) > min(pre_infor): #The length and width of the bottom surface of the newly stacked box (i.e. the maximum and minimum values of the first two elements in the combined data, which correspond to the length and width of the bottom surface respectively) must be less than the length and width of the bottom surface of the lower box respectively return # Otherwise, it indicates that it cannot be stacked and returns directly ### 2 update box Height if sum + start[2] >self.ways: self.ways = sum + start[2] ### 3. Judge whether to terminate if step >= size: return #### 4 enter DFS recursion ###4.1 first, check the boxes that have been visited new_queue = [] new_queue.append('*') # To ensure the order of the queue, add an element in advance and delete it later for qi in queue: new_queue.append(qi) new_queue.pop(0) ###4.2 entering the cycle for i in range(size): if i not in new_queue:#If it has not been accessed, it can be accessed new_queue.append(i)# Join the accessed queue for j in range(3):# Process the three cases of the current box in turn new_start = new_data[i][j] self.dfs(start,new_start,sum+start[2],step+1,new_queue) #### Before the next for loop, pop up the previously accessed box so that all boxes can be used as the second bottom box new_queue.pop() # This step is particularly important return ## Welcome data # Total number of test cases N = int(input().strip()) data = [] data_size = [] for case in range(N): size = int(input().strip()) data_size.append(size) ### temp = [] for di in range(size): temp.append(list(map(int,input().strip().split(' ')))) data.append(temp) # print(data) ############# handle ############## for case in range(N): ### Extract information size = data_size[case] subdata = data[case] #### data processing new_data = proData(size,subdata) # print(new_data) #### DFS handle ######### test = Solution() ans = test.DFS() #### Print results print('#'+str(case+1)+' '+str(ans))
Input:
2 2 76 25 3 24 23 4 3 85 20 23 43 18 90 29 12 45
Output:
#1 76 #2 158