【 每日一题】05 三角形最小路径和(DP4)

问题描述

给定一个三角形 triangle ,找出自顶向下的最小路径和。

每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。

示例 1:

输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]

输出:11

解释:如下面简图所示:

2

3 4

6 5 7

4 1 8 3

自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

解答

首先,既然是从上到下的路径,那么最后一个点必然是落在最后一行。

对于最后一行的某个位置的值,根据题意只能从上一行的某一个位置或者某两个位置之一转移而来。

同时,我们只关注前一位的累加值是多少,而不关心这个累加值结果是由什么路径而来的。

f[i][j] 代表到达某个点的最小路径和。

通过观察可以发现以下性质:

  1. 只要不是第一列(j!=0)位置上的数,都能通过「左上方」转移过来
  2. 只要不是每行最后一列(j!=i)位置上的数,都能通过「上方」转移而来

同时,这样的分析/转移过程,是可以推广并覆盖所有位置的。

至此,整个过程都没有问题,状态转移方程也能不重不漏的枚举到每一条路径。因此这个 DP 状态定义可用。

c 复制代码
int minimumTotal(int** triangle, int triangleSize, int* triangleColSize) {

    int ** f = (int **)malloc(sizeof(int *)* triangleSize);
    for(int i =0; i<triangleSize; i++){
        f[i] = (int *)malloc(sizeof(int) * triangleColSize[i]);
    }
    f[0][0] = triangle[0][0];
    

    int i, j;
    for(i=1; i<triangleSize; i++){
        for(j=0; j< triangleColSize[i]; j++){
            f[i][j] = 10000;
            //若不是j==0的位置,可以通过左上方转移
            if(j!=0){
                f[i][j] = fmin(f[i-1][j-1]+ triangle[i][j],  f[i][j]);
            }
            if(j!=(triangleColSize[i]-1)){
                f[i][j] = fmin(f[i-1][j]+ triangle[i][j],  f[i][j]);
            }
        }
    }
    
    int ans = 1e9;

    for(j =0 ;j<triangleColSize[triangleSize-1]; j++){
        ans = fmin(ans, f[triangleSize-1][j]);

    }

    return ans;
    
}
相关推荐
CoovallyAIHub3 分钟前
YOLO-IOD深度解析:打破实时增量目标检测的三重知识冲突
深度学习·算法·计算机视觉
NAGNIP11 小时前
轻松搞懂全连接神经网络结构!
人工智能·算法·面试
NAGNIP11 小时前
一文搞懂激活函数!
算法·面试
董董灿是个攻城狮11 小时前
AI 视觉连载7:传统 CV 之高斯滤波实战
算法
爱理财的程序媛17 小时前
openclaw 盯盘实践
算法
MobotStone21 小时前
Google发布Nano Banana 2:更快更便宜,图片生成能力全面升级
算法
颜酱1 天前
队列练习系列:从基础到进阶的完整实现
javascript·后端·算法
用户5757303346241 天前
两数之和:从 JSON 对象到 Map,大厂面试官到底在考察什么?
算法
程序猿追1 天前
“马”上行动:手把手教你基于灵珠平台打造春节“全能数字管家”
算法