120. 三角形最小路径和-动态规划

问题描述

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。

例如,给定三角形:

[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

说明:

如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/triangle

解答

'''

动态规划。时间复杂度:O(n^2),空间复杂度O(n)
1.原问题:到达第n层的最小开销
2.dp[i]表示每个不同走法带来的开销,其中i=len(triangle)
3.边界值:dp[0] = triangle[0][0]
4.状态转移方程:
    dp[i] = min(能走到i的全部可能)

还有一种动态规划解法,就是申请一个和三角形一样的二维数组,dp[i][j]表示到达triangle[i][j]的最优解;可以从上往下遍历,也可以从下往上遍历。

'''
class Solution(object):
    def minimumTotal(self, triangle):
        lens = 0
        for i in triangle:
            lens += len(i)
        if lens == 1:
            return triangle[0][0]
        dp = [0 for _ in range(lens)]
        dp[0] = triangle[0][0]
        p = 1
        q = 1
        for j in range(1,len(triangle)):
            k = len(triangle[j])
            for n in range(0,len(triangle[j])-1):
                if dp[n+p] == 0:
                    dp[n+p] = triangle[j][n] + dp[p+n-q]
                else:
                    if  dp[n+p] > triangle[j][n] + dp[p+n-q]:
                        dp[n+p] = triangle[j][n] + dp[p+n-q]
                print(n+p, triangle[j][n], dp[p+n-q])
            for n in range(1,len(triangle[j])):
                if dp[n+p] == 0:
                    dp[n+p] = triangle[j][n] + dp[p+n-q-1]
                else:
                    if  dp[n+p] > triangle[j][n] + dp[p+n-q-1]:
                        dp[n+p] = triangle[j][n] + dp[p+n-q-1]
                print(n+p, triangle[j][n], dp[p+n-q-1])
            p += len(triangle[j])
            q+=1
        mins = dp[lens-1]
        for i in range(lens-1 ,lens - len(triangle[-1])-1 , -1):
            if mins > dp[i]:
                mins = dp[i]
        return mins
原文地址:https://www.cnblogs.com/xxxxxiaochuan/p/13065552.html