动态规划应用--“杨辉三角”最短路径 & LeetCode 120

1. 问题描述

对“杨辉三角"进行一些改造。每个位置的数字可以随意填写,经过某个数字只能到达下面一层相邻的两个数字。
假设你站在第一层,往下移动,我们把移动到最底层所经过的所有数字之和,定义为路径的长度。请你编程求出从最高层移动到最底层的最短路径。
在这里插入图片描述

2. DP算法代码

/**
 * @description: 改造的杨辉三角,从顶层下来的最小和
 * @author: michael ming
 * @date: 2019/7/17 23:03
 * @modified by: 
 */
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;
const int high = 5;
int YHTriangle[high][high] = {{5},{7,8},{2,1,4},{4,2,6,1},{2,7,3,4,5}};

void shortestPath()
{
    int states[high][high];//存放路径距离(存较小的)
//    memset(states,65535,high*high*sizeof(int));
    states[0][0] = YHTriangle[0][0];//第一个点的距离
    int i, j;
    for(i = 1; i < high; ++i)//动态规划
    {
        for(j = 0; j <= i; ++j)
        {
            if(j == 0)//在两边,上一个状态没得选,只有一个
                states[i][j] = states[i-1][j]+YHTriangle[i][j];
            else if(j == i)//在两边,上一个状态没得选,只有一个
                states[i][j] = states[i-1][j-1]+YHTriangle[i][j];
            else//在中间,上一个状态有两个,选路径短的
                states[i][j] = min(states[i-1][j],states[i-1][j-1])+YHTriangle[i][j];
        }
    }
    int mins = 65535, idx;
    for(j = 0; j < high; ++j)
    {
        if(mins > states[high-1][j])
        {
            mins = states[high-1][j];//选出最短的
            idx = j;//记录最短的路径位置
        }
    }
    cout << "最短的路径是:" << mins << endl;
    //-----------打印路径-----------------------
    cout << "从底向上走过的点的值是:" << endl;
    cout << YHTriangle[high-1][idx] << " ";
    for(i = high-1,j = idx; i > 0; --i)
    {
        if(j == 0)
            cout << YHTriangle[i-1][j] << " ";
        else if(j == i)
        {
            cout << YHTriangle[i-1][j-1] << " ";
            j--;
        }
        else
        {
            if(states[i-1][j-1] < states[i-1][j])
            {
                cout << YHTriangle[i-1][j-1] << " ";
                j--;
            }
            else
                cout << YHTriangle[i-1][j] << " ";
        }
    }
}
int main()
{
    shortestPath();
    return 0;
}

在这里插入图片描述


更改数据再测试
在这里插入图片描述
在这里插入图片描述

3. LeetCode 120 三角形最小路径和

https://leetcode-cn.com/problems/triangle/
在这里插入图片描述
以下解法是O(n)空间复杂度

class Solution 
{
public:
    int minimumTotal(vector<vector<int>>& triangle) 
    {
    	int n = triangle.size();
        int states[n];
        int temp_states[n];
        states[0] = triangle[0][0];
        int i, j, k, minsum = INT_MAX;
        for (i = 1; i < n; i++)
        {
        	for(j = 0; j < i+1; j++)
        	{
        		if(j == 0)
        			temp_states[0] = states[0] + triangle[i][j];
        		else if(j == i)
        			temp_states[j] = states[j-1] + triangle[i][j];
        		else
        			temp_states[j] = min(states[j-1], states[j]) + triangle[i][j];
        	}
        	for(k = 0; k < i+1; k++)
        		states[k] = temp_states[k];//更新states
        }
        for(j = 0; j < n; j++)//求最小的值
        {
        	if(states[j] < minsum)
        		minsum = states[j];
        }
        return minsum;
    }
};
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Michael阿明

如果可以,请点赞留言支持我哦!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值