拜访--美团笔试题 (动态规划)

现在有一个城市销售经理,需要从公司出发,去拜访市内的商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他只能在左右中选择一个方向,在上下中选择一个方向,现在问他有多少种方案到达商家地址。

给定一个地图map及它的长宽nm,其中1代表经理位置,2代表商家位置,-1代表不能经过的地区,0代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于10。

测试样例:
[[0,1,0],[2,0,0]],2,3
返回:2
# -*- coding:utf-8 -*-
class Visit:
    def countPath(self, map, n, m):
        # write code here
        if n <= 0 or m <= 0:   # 健壮性
            return -1
        #遍历整个地图获得起始点和终止点
        start = []
        end = []
        for i in range(n):      # 找出起始点和终点的坐标值
            for j in range(m):
                if map[i][j] == 1:
                    start.append(i)   #注意此处的赋值语句
                    start.append(j)
                    map[i][j] = 0     # 并把这个点设为0,为后续的判断提供方便(重要)
                if map[i][j] == 2:
                    end.append(i)
                    end.append(j)
                    map[i][j] = 0     # 并把这个点设为0,为后续的判断提供方便(重要)
        rows = abs(start[0] - end[0]) + 1   # 起始点和终点构成的矩阵的行数
        cols = abs(start[1] - end[1]) + 1   #                     列数
        f = [[0 for col in range(cols)] for row in range(rows)] # 存放中间结果值
        
        if start[0] > end[0]: # 调整起始点和终点的位置关系,使得起点总是在上边
            tmp0 = start[0]
            tmp1 = start[1]
            start[0] = end[0]
            start[1] = end[1]
            end[0] = tmp0
            end[1] = tmp1
        if start[1] == end[1]:       # 在同一列
            return 1
        if start[0] == end[0]:       # 在同一行
            return 1
        #  分为两种情况,一种是向右或向下走,另一种是向左或向下走
        if start[1] < end[1]:       # 向右向下行走
            f[0][0] = 1              # 初始状态
            for i in range(1,cols):    #单独的一行处理
                if map[start[0]][start[1] + i] == -1:
                    f[0][i] = 0      # 第一行从第二个元素起
                if map[start[0]][start[1] + i] == 0:
                    f[0][i] = f[0][i-1]
            for j in range(1,rows):        #单独的一列处理
                if map[start[0] + j][start[1]] == -1:
                    f[j][0] = 0
                if map[start[0] + j][start[1]] == 0:
                    f[j][0] = f[j-1][0]
            for i in range(1,cols):
                for j in range(1,rows):
                    if map[start[0] + j][start[1] + i] == -1:
                        f[j][i] = 0
                    if map[start[0] + j][start[1] + i] == 0:
                        f[j][i] = f[j - 1][i] + f[j][i - 1]
            return f[rows - 1][cols - 1]
        
        if start[1] > end[1]:       # 向左向下行走
            f[0][cols - 1] = 1
            for i in range(1,cols):        #单独的一行处理
                if map[start[0]][start[1] - i] == -1:
                    f[0][cols - 1 - i] = 0       # 第一行右起第二个元素
                if map[start[0]][start[1] - i] == 0:
                    f[0][cols - 1 - i] = f[0][cols - 1 - i + 1]
            for j in range(1,rows):        #单独的一列处理
                if map[start[0] + j][start[1]] == -1:
                    f[j][cols - 1] = 0
                if map[start[0] + j][start[1]] == 0:
                    f[j][cols - 1] = f[j-1][cols - 1]
            for i in range(1,cols):
                for j in range(1,rows):
                    if map[start[0] + j][start[1] - i] == -1:
                        f[j][cols - 1 - i] = 0
                    if map[start[0] + j][start[1] - i] == 0:
                        f[j][cols - 1 - i] = f[j - 1][cols - 1 - i] + f[j][cols - 1 - i - 1]
            return f[rows - 1][0]
        
        
原文地址:https://www.cnblogs.com/simplepaul/p/7256335.html