2017阿里内推笔试题–算法工程师
'''
沐哲是一个菜鸟仓库的一个拣货员,但他有非常个怪异的习惯。每次拣货的重量都要比之前拣的一个轻,每次拣到货后都可以得到1块钱,沐哲想知道这样最多能赚多少钱
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
沐哲可以从仓库的某个货架开始拣货,下一步可以往上走,也可以往下走,当然,向左向右也可以,但必须使得下一个货物重量减小,才会去拣。在上面的仓库中,一条可拣货的路径为 25-22-3。
当然30-23-20-16-13-12-3可以拣的货更多。这也是赚钱最多的一条路径。
'''
'''
动态规划法:
说明:利用动态规划的思想,从最大步数最少的元素找起,那么最大步数为s的元素的上下左右四个位置一定存在第s-1步的元素.以此为判断条件结合辅助条件来给矩阵赋值.
算法步骤:
1.令P为一个与初始货架重量矩阵同维度的步数矩阵(初始元素都为0)
2.s=1,即最大步长为1开始
3.矩阵中元素满足上下左右位置的元素都大于该元素,则该元素的最大步长为1
4.从s=2开始,取矩阵中未赋值的元素(即=0的元素),进行逐个判断
5.判断条件1:该元素的上下左右四个元素中至少存在最大步长为(s-1)步的元素
6.判断条件2:若满足判断条件1,则上下左右除去(s-1)元素外,若其余位置比该元素小的元素都已经赋值,也即它只能被进入而不能超其他方向走;或者其余位置都比该元素大时,则该元素即为(s+1)步元素
7.重复3-6步,直至矩阵所以元素都已赋值时结束.
'''
def function(L, row, col):
maxlen = 0
P = [[0 for i in range(col)] for j in range(row)]
time = row * col
print('time = ',time)
N = []
s = 1
for i in range(row):
for j in range(col):
ok = True
if i-1 > 0 and L[i][j] > L[i-1][j]:
ok = False
if i+1 < row and L[i][j] > L[i+1][j]:
ok = False
if j-1 > 0 and L[i][j] > L[i][j-1]:
ok = False
if j+1 < col and L[i][j] > L[i][j+1]:
ok = False
if ok:
P[i][j] = s
N.append([i,j])
time -= 1
print('P = ',P)
s += 1
while time > 0:
print(time)
NowN = []
for i in range(len(N)):
NowN.append(N[i])
print('s = ',s)
print('NowN = ',NowN)
for l in NowN:
i = l[0]
j = l[1]
print('i = {}, j = {} '.format(i, j))
if i-1 >= 0:
i_n = i-1
j_n = j
print('i-1的计算')
print('i_n = {}, j_n = {} '.format(i_n, j_n))
if(P[i_n][j_n] == 0):
ok = True
if i_n-1 >= 0 and L[i_n][j_n] > L[i_n-1][j_n] and P[i_n-1][j_n] == 0:
ok = False
if j_n-1 >= 0 and L[i_n][j_n] > L[i_n][j_n-1] and P[i_n][j_n-1] == 0:
ok = False
if j_n+1 < col and L[i_n][j_n] > L[i_n][j_n+1] and P[i_n][j_n+1] == 0:
ok = False
if ok:
P[i_n][j_n] = s
N.append([i_n,j_n])
time -= 1
if i+1 < row:
i_n = i+1
j_n = j
print('i+1的计算')
print('i_n = {}, j_n = {} '.format(i_n, j_n))
if(P[i_n][j_n] == 0):
ok = True
if i_n+1 < row and L[i_n][j_n] > L[i_n+1][j_n] and P[i_n+1][j_n] == 0:
ok = False
if j_n-1 >= 0 and L[i_n][j_n] > L[i_n][j_n-1] and P[i_n][j_n-1] == 0:
ok = False
if j_n+1 < col and L[i_n][j_n] > L[i_n][j_n+1] and P[i_n][j_n+1] == 0:
ok = False
if ok:
P[i_n][j_n] = s
N.append([i_n,j_n])
time -= 1
if j-1 >= 0:
i_n = i
j_n = j-1
print('j-1的计算')
print('i_n = {}, j_n = {} '.format(i_n, j_n))
if(P[i_n][j_n] == 0):
ok = True
if i_n-1 >= 0 and L[i_n][j_n] > L[i_n-1][j_n] and P[i_n-1][j_n] == 0:
ok = False
if i_n+1 < row and L[i_n][j_n] > L[i_n+1][j_n] and P[i_n+1][j_n] == 0:
ok = False
if j_n-1 >= 0 and L[i_n][j_n] > L[i_n][j_n-1] and P[i_n][j_n-1] == 0:
ok = False
if ok:
P[i_n][j_n] = s
N.append([i_n,j_n])
time -= 1
if j+1 < col:
i_n = i
j_n = j+1
print('j+1的计算')
print('i_n = {}, j_n = {} '.format(i_n, j_n))
if(P[i_n][j_n] == 0):
ok = True
if i_n-1 >= 0 and L[i_n][j_n] > L[i_n-1][j_n] and P[i_n-1][j_n] == 0:
ok = False
if i_n+1 < row and L[i_n][j_n] > L[i_n+1][j_n] and P[i_n+1][j_n] == 0:
ok = False
if j_n+1 < col and L[i_n][j_n] > L[i_n][j_n+1] and P[i_n][j_n+1] == 0:
ok = False
if ok:
P[i_n][j_n] = s
N.append([i_n,j_n])
time -= 1
N.remove([i,j])
s += 1
return(P,s-1)
L = [[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] ]
(P,s) = function(L, 6, 6)
print('P = ',P)
print('s = ',s)
输出结果:
P = [[4, 5, 2, 3, 2, 1], [3, 2, 1, 2, 5, 6], [4, 7, 2, 1, 4, 1], [5, 6, 7, 2, 3, 4], [6, 3, 2, 3, 4, 1], [1, 4, 1, 2, 5, 2]]
s = 7