三角数字自上而下求最值和【dfs+动规】

本文介绍了解决LeetCode题目120. Triangle的方法,包括原始DFS、带备忘录的DFS及动态规划三种解题思路,并提供了详细的C语言代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

leetcode: 120. Triangle

一、问题描述

给定一个三角形,找到从顶部到底部的最小路径和。可以移动到下一行的相邻数字的每一步。
【举例】
[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]
自上而下的最小和为 11( 2 + 3 + 5 + 1 = 11).

二、解题思路
本题可采用dfs和动态规划两种方法求解,下面分别使用dfs和动态规划思想解这道题。

三、算法实现

1、DFS --- 原生dfs,会超时

/******************************************************
Author:tmw
date:2018-5-18
*******************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define min( a,b ) ( a<b?a:b )

/**方法一:dfs--不加备忘录的---超时**/
int dfs( int** triangle, int RowSize, int ColSizes, int i, int j )
{
    //终止条件
    if( i<j || i>RowSize )  return INT_MAX;

    //收敛条件
    if( i == RowSize-1 ) return triangle[i][j];

    //递归 -- 左或右
    return min(dfs(triangle,RowSize,ColSizes,i+1,j),dfs(triangle,RowSize,ColSizes,i+1,j+1))+triangle[i][j];
}

int minimumTotal(int** triangle, int triangleRowSize, int *triangleColSizes)
{
    int sum = dfs(triangle,triangleRowSize,triangleRowSize,0,0);
    *triangleColSizes = triangleRowSize;
    return sum;
}

2、DFS --- 加缓存的备忘录dfs,accept

/******************************************************
Author:tmw
date:2018-5-19
*******************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

/**方法二:dfs--加备忘录**/
#define min( a,b ) ( a<b?a:b )
#define MAX_SIZE 200
//备忘录数组--record  ---之前把record放到全局变量的位置测试例通不过,放到局部变量里就通了。。。
int dfs( int** triangle, int RowSize, int ColSize, int i, int j, int** record )
{
    if( record[i][j] != INT_MAX ) return record[i][j];

    //终止条件
    if( i < j || i > RowSize )  return 0;

    //收敛条件
    if( i == RowSize-1 ) return triangle[i][j];

    record[i][j] = min(dfs(triangle,RowSize,ColSize,i+1,j,record),dfs(triangle,RowSize,ColSize,i+1,j+1,record))+triangle[i][j];

    return record[i][j];
}
int minimumTotal(int** triangle, int triangleRowSize, int *triangleColSizes)
{
    int i,j;
    int** record = (int**)malloc(MAX_SIZE*sizeof(int*));
    for( i=0; i<MAX_SIZE; i++ )
        record[i] = (int*)malloc(MAX_SIZE*sizeof(int));
    for( i=0; i<triangleRowSize; i++ )
        for( j=0; j<triangleRowSize; j++ )
            record[i][j] = INT_MAX;

    int sum = dfs(triangle,triangleRowSize,triangleRowSize,0,0,record);
    *triangleColSizes = triangleRowSize;
    return sum;
}

3、动态规划,accept

/******************************************************
Author:tmw
date:2018-5-19
*******************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

//方法三 --- 动态规划  --- 自底向上的思路
#define MAX_SIZE 200
#define min( a,b ) ( a<b?a:b )
int minimumTotal(int** triangle, int triangleRowSize, int *triangleColSizes)
{
    int i,j;

    for( i=triangleRowSize-2; i>=0; i-- ) //自底向上
        for( j=0; j<=i; j++ )
            triangle[i][j] = min( triangle[i+1][j], triangle[i+1][j+1] ) + triangle[i][j];

    *triangleColSizes = triangleRowSize;
    return triangle[0][0];
}


梦想还是要有的,万一实现了呢~~~~ヾ(◍°∇°◍)ノ゙~~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值