Minimum Path Sum

本文通过对比Dijkstra算法与动态规划解决最小路径和问题的方法,揭示了动态规划在此类问题上的优势。通过具体实例展示了两种算法的设计思路及实现代码,最终得出动态规划不仅简洁而且效率更高。

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

题目

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

分析

    乍看到这个题目我还以为是个图的最小路径问题,受到先入为主的影响,我dijkstra算法求解,后来运行超出时间限制,因为其算法复杂度高达O(n^2xm),其代码如下:
class Solution{
public:
    int minPathSum(vector<vector<int> >& grid){
    	int n = grid.size();
    	int m = grid[0].size();
        vector<vector<pair<int,bool> > > pv(n,vector<pair<int,bool> >(m,make_pair(2147483647,false)));
        pv[0][0].first = grid[0][0];
        set<pair<int,int> > s;
        s.insert(make_pair(0,0));
        while (true)
        {
        	pair<int,int> min = make_pair(n-1,m-1);
        	set<pair<int,int> >::iterator minp = s.begin();
        	for (set<pair<int,int> >::iterator p = s.begin();p!=s.end();p++)
        		if ((!pv[p->first][p->second].second) && pv[p->first][p->second].first < pv[min.first][min.second].first)
        		{
        			min.first = p->first;
        			min.second = p->second;
        			minp = p;
        		}
        	if (min.first == n-1 && min.second == m-1)
        		return pv[n-1][m-1].first;
        	pv[min.first][min.second].second = true;
        	s.erase(minp);
        	if (min.second < m - 1 && pv[min.first][min.second+1].second == false)
        		if (pv[min.first][min.second].first + grid[min.first][min.second+1] < pv[min.first][min.second+1].first)
        		{
        			pv[min.first][min.second+1].first = pv[min.first][min.second].first + grid[min.first][min.second+1];
        			s.insert(make_pair(min.first,min.second+1));
				} 
        	if (min.first < n - 1 && pv[min.first+1][min.second].second == false)
        		if (pv[min.first][min.second].first + grid[min.first+1][min.second] < pv[min.first+1][min.second].first)
        		{
        			pv[min.first+1][min.second].first = pv[min.first][min.second].first + grid[min.first+1][min.second];
        			s.insert(make_pair(min.first+1,min.second));
				}
		}
    }
};

可见代码冗长且复杂度高

后来在参考了别人的思想之后才发现这是一个典型的动态规划问题,假设到达(i,j)的最小路径和为S[i][j],则状态转移方程为S[i][j] = min(S[i-1][j],S[i][j-1])+grid[i][j]。需要

注意的是边界问题,代码如下:

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        vector<int> cur(m, grid[0][0]);
        for (int i = 1; i < m; i++)
            cur[i] = cur[i - 1] + grid[i][0]; 
        for (int j = 1; j < n; j++) {
            cur[0] += grid[0][j]; 
            for (int i = 1; i < m; i++)
                cur[i] = min(cur[i - 1], cur[i]) + grid[i][j];
        }
        return cur[m - 1];
    }
};
简洁而直观,并且复杂度降低了一个数量级。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值