【 每日一题】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;
    
}
相关推荐
长安er5 小时前
LeetCode215/347/295 堆相关理论与题目
java·数据结构·算法·leetcode·
元亓亓亓5 小时前
LeetCode热题100--62. 不同路径--中等
算法·leetcode·职场和发展
小白菜又菜5 小时前
Leetcode 1925. Count Square Sum Triples
算法·leetcode
登山人在路上6 小时前
Nginx三种会话保持算法对比
算法·哈希算法·散列表
写代码的小球7 小时前
C++计算器(学生版)
c++·算法
AI科技星7 小时前
张祥前统一场论宇宙大统一方程的求导验证
服务器·人工智能·科技·线性代数·算法·生活
Fuly10248 小时前
大模型剪枝(Pruning)技术简介
算法·机器学习·剪枝
Xの哲學8 小时前
Linux网卡注册流程深度解析: 从硬件探测到网络栈
linux·服务器·网络·算法·边缘计算
bubiyoushang8888 小时前
二维地质模型的表面重力值和重力异常计算
算法
仙俊红8 小时前
LeetCode322零钱兑换
算法