leetcode 3651

3651: 带传送的最小路径成本

如果没有传送,本题就是leetcode 64:最小路径和。注意本题不计入起点的值。

在有传送的情况下,可以用一个额外的维度表示传送次数。定义 f[t][i+1][j+1] 表示++在恰好使用 t 次传送的情况下,从左上角 (0,0) 到 (i,j) 的最小总成本。++

传送条件只依赖于格子的数值,而不依赖于位置。

min_f [x] 表示++格子值为 x++的最小状态值(如果不存在则为 ∞)。【从左上角 (0,0) 到任一格子值为x中的最小总成本】

suf_min_f [x] 表示格子值 >=x 的最小状态值。计算方法:倒序遍历min_f,一层一层更新格子值 >=x 的最小状态值。(最大格子值为mx)

复制代码
//更新后缀最小值
for(int i=mx;i>=0;i--){
    suf_min_f[i]=min(suf_min_f[i+1],min_f[i]);
}

答案为 f[k][m][n]。虽然题目要求使用「至多」k 次传送,但由于我们可以原地传送,所以传送的次数越多,总成本是不会增大的。所以「至多」k 次传送等于「恰好」k 次传送。

代码实现时,f 数组的前两个维度可以优化掉。

复制代码
class Solution {
public:
    int minCost(vector<vector<int>>& grid, int k) {
        int n=grid[0].size();
        int mx=0;
        for(auto& row:grid){
            mx=max(mx,ranges::max(row)); //找到最大的格子值x
        }
        vector<int> suf_min_f(mx+2,INT_MAX);
        vector<int> min_f(mx+1);
        vector<int> f(n+1);
        for(int t=0;t<=k;t++){
            ranges::fill(min_f,INT_MAX);
            //最小路径和(空间优化写法)
            ranges::fill(f,INT_MAX/2);
            f[1]=-grid[0][0]; //起点的成本不算
            for(auto& row:grid){
                for(int j=0;j<n;j++){
                    int x=row[j];
                    f[j+1]=min(min(f[j],f[j+1])+x,suf_min_f[x]);
                    min_f[x]=min(min_f[x],f[j+1]);
                }
            }
            //倒序计算后缀最小值,供下一轮t+1使用
            for(int i=mx;i>=0;i--){
                suf_min_f[i]=min(suf_min_f[i+1],min_f[i]);
            }
        }

        return f[n];
    }
};
相关推荐
2302_813806228 分钟前
【嵌入式修炼:数据结构篇】——数据结构总结
数据结构
Wei&Yan31 分钟前
数据结构——顺序表(静/动态代码实现)
数据结构·c++·算法·visual studio code
团子的二进制世界1 小时前
G1垃圾收集器是如何工作的?
java·jvm·算法
吃杠碰小鸡1 小时前
高中数学-数列-导数证明
前端·数学·算法
故事不长丨1 小时前
C#线程同步:lock、Monitor、Mutex原理+用法+实战全解析
开发语言·算法·c#
long3161 小时前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
近津薪荼1 小时前
dfs专题4——二叉树的深搜(验证二叉搜索树)
c++·学习·算法·深度优先
熊文豪1 小时前
探索CANN ops-nn:高性能哈希算子技术解读
算法·哈希算法·cann
熊猫_豆豆2 小时前
YOLOP车道检测
人工智能·python·算法
艾莉丝努力练剑2 小时前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法