Crop Hybridization [Eleventh Session] [Provincial Competition] [Group B] Python [Recursive + Memory Search + Reversed dfs + dp]

Title Description
Crop hybridization is an important step in crop cultivation. It is known that there are N kinds of crops (numbered 1 to N ), and the time from sowing to maturity of the i-th crop is Ti. Crops can be hybridized in pairs, and the hybridization time is the longer one of the two species. For example, the planting time of crop A is 5 days, and the planting time of crop B is 7 days, then the time for AB hybridization is 7 days. Crop hybridization will produce fixed crops, and the newly generated crops still belong to one of the N crops.
At the beginning, there are seeds of M kinds of crops (the number is unlimited, and multiple crosses can be supported). Multiple hybridization processes can be performed simultaneously. Ask how many days are needed to obtain a given target seed.
If there are 4 kinds of crops ABCD, their respective maturity times are 5 days, 7 days, 3 days, and 8 days. Initially there are seeds of two crops AB, the target seed is D, and the known hybridization situation is A × B → C, A × C → D. Then the shortest hybridization process is:
from the 1st day to the 7th day (the time of crop B), A × B → C.
Day 8 to Day 12 (the time of crop A), A × C → D.
It takes 12 days to get the seeds of crop D.

Input description
The first line of input contains 4 integers N, M, K, T, N represents the total number of crop types (number 1 to N), M represents the number of crop seed types initially owned, K represents the number of hybridization schemes, T Indicates the number of the target seed.
Line 2 contains N integers, of which the i-th integer represents the planting time Ti of the i-th crop (1<=Ti<=100) and line 3 contains
M integers, respectively representing the type of seeds Kj (1 < = Kj ≤ M), Kj are different in pairs.
Lines 4 to K+ 3, each line contains 3 integers A, B, C, which means that the seeds of type C crops can be obtained by crossing type A crops with type B crops.
Among them, 1 <= N<= 2000, 2<= M <= N, 1 <= K <=10^5, 1 <= T <= N to ensure that the target seed can be obtained through hybridization
.

Output Description
Output an integer, indicating the shortest hybridization time to get the target seed.

sample input

6 2 4 6
5 3 4 6 4 9
1 2
1 2
3 1 3
4 2 3
5 4 5 6
sample output

16
Sample Description

From the 1st day to the 5th day, the crop number 1 was crossed with the crop number 2 to obtain the crop seed number 3.
From the 6th day to the 10th day, the crop number 1 was crossed with the crop number 3 to obtain the crop seed number 4.
From the 6th day to the 9th day, the crop number 2 was crossed with the crop number 3 to obtain the crop seed number 5.
From the 11th day to the 16th day, the crop number 4 was crossed with the crop number 5 to obtain the crop seed number 6.
In total it took 16 days.

analyze:

1 Read the question carefully first! Don't worry
2 When writing code, it is best to write data samples next to it, which is convenient for programming!
3 When coding, print more intermediate results and find the rules! Especially recursion! !

Idea:
If we want to obtain crop No. 6, we need to obtain crop No. 4 5 and its shortest hybridization time first, and obtaining crop No. 4 5 is another recursive search! So reverse search

Considering dfs, go backwards from the target until you search for known crops,
do a memorized search to prevent timeouts! Set what to search for, and definitely set the shortest time to get the i-th crop

min_time[i] records the shortest time to obtain the i-th crop, the default is infinite float ("inf") (a bit like dp, but not all...), if min_time has been searched, it will return directly, if it has not been searched words = min(self, new hybrid scheme)

Because if you want to find the smallest one, you must compare it with yourself and take min

Another pitfall to note here is: there is not necessarily only one hybridization scheme for a crop, so don’t be fooled by the examples!

In dfs, we traverse all the hybridization schemes of i for recursion. This involves how to store the i hybridization scheme. Here, mix[i] is used to represent the hybridization scheme of i.
Two-dimensional, each mix[i] is a list, storing multiple hybridization schemes

Such as mix=[[], [], [], [[1, 2, 5]], [[1, 3, 5]], [[2, 3, 4]], [[4, 5, 6 ]]]
mix[i]: hybrid scheme i: target crop

The core code in memory search

 for j in range( len(mix[i])):#遍历i作物的所有杂交方案j=0 1 2
    min_time[i]=min(min_time[i],max(dfs(mix[i][j][0]),dfs(mix[i][j][1]))+mix[i][j][2])
    #min_time[i]=min(本身已经最小不更新,max(获取a作物的最短时间,获取b作物的最短时间)+杂交ab作物的时间)

Be sure to understand the idea of ​​recursion, don't delve into it,
you can push it by hand when necessary to find the law

			#min_time[6]=min(inf,max(dfs(4),dfs(5))+6h)=16h
            #min_time[5]=min(inf,max(dfs(2),dfs(3))+4h)=9h
            #min_time[4]=min(inf,max(dfs(1),dfs(3))+5h)=10h
            #min_time[3]=min(inf,max(dfs(1),dfs(2))+5h)=5h
            #dfs(1)=0 #dfs(2)=0 

the code

n,m,k,t=map(int,input().split())
cost=list(map(int,input().split()))
have = list(map(int,input().split()))

mix=[[] for i in range(n+1)]#杂交列表初始化为空,每个植物都有对应mix[i]代表第i种作为
for i in range(k):
  a,b,c=map(int,input().split())#杂交方案 1+2→3 #1+3→4 #2+3→5 #4+5→6
  max_time = max(cost[a - 1], cost[b - 1])
  ls = [a, b, max_time]  # ls=[种子a,种子b,杂交最长时间] [1,2,5] [1,3,5] [2,3,4] [4,5,6]
  mix[c].append(ls)#mix=[[], [], [], [[1, 2, 5]], [[1, 3, 5]], [[2, 3, 4]], [[4, 5, 6]]]
  # [[[],[],[]]]这种格式是因为一种作物可能存在多种杂交方案?对!例如第三种作物可以有两种杂交方式[[1, 2, 5],[5,1,5]]
  # mix[i]:杂交方案 i:目标作物

min_time=[float("inf") for i in range(n+1)]#每种作物培养时间初始化为无穷大,因为要找最小的
for i in have:
  min_time[i]=0#min_time=[0,0,0,inf,inf,inf···]

def dfs(i):#搜索获取目标作物的最短时间,记忆化搜索
  if min_time[i] !=float("inf"):return min_time[i]


  for j in range( len(mix[i])):#i作物的所有杂交方案j=0 1 2
    min_time[i]=min(min_time[i],max(dfs(mix[i][j][0]),dfs(mix[i][j][1]))+mix[i][j][2])
    #min_time[i]=min(本身已经最小不更新,max(获取a作物的最短时间,获取b作物的最短时间)+杂交ab作物的时间)
			#min_time[6]=min(inf,max(dfs(4),dfs(5))+6h)=16h
            #min_time[5]=min(inf,max(dfs(2),dfs(3))+4h)=9h
            #min_time[4]=min(inf,max(dfs(1),dfs(3))+5h)=10h
            #min_time[3]=min(inf,max(dfs(1),dfs(2))+5h)=5h
            #dfs(1)=0 #dfs(2)=0 

  return min_time[i]

#print(have)
#print(mix)
dfs(t)
print(min_time[t])


Guess you like

Origin blog.csdn.net/weixin_45837404/article/details/124025374