leetcode 3651

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

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

在有传送的情况下,可以用一个额外的维度表示传送次数。定义 fti+1j+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]);
}

答案为 fkmn。虽然题目要求使用「至多」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];
    }
};
相关推荐
萧西待水3 小时前
奥赛一本通 1451 棋盘游戏
算法·宽度优先
Niuguangshuo3 小时前
论文解读:Paraformer,非自回归中文 ASR 的并行 Transformer
算法·音视频·语音识别
鹿角片ljp4 小时前
LeetCode 78:子集|回溯、选与不选、递归和path快照
java·数据结构·算法
圣保罗的大教堂4 小时前
leetcode 2033. 获取单值网格的最小操作数 中等
leetcode
YSL0701244 小时前
顺序表小补充
数据结构
hansang_IR4 小时前
【代数与组合数学 | 那忘算 5】生成函数 & 例题 & 卷积
c++·算法·多项式·生成函数·母函数
Zane19944 小时前
快速排序凭什么叫"快"排序?平均O(nlogn)背后,藏着一个能让它退化成O(n²)的选择
算法
6Hzlia4 小时前
【Classic 150 刷题计划】 LeetCode 242. 有效的字母异位词 | C++ 哈希计数与严密防线
c++·算法·leetcode
wabs6664 小时前
关于二叉树【力扣101.对称二叉树的思考】
数据结构·c++·算法·leetcode·二叉树
6Hzlia4 小时前
【Classic 150 刷题计划】 LeetCode 228. 汇总区间 | C++ 双游标区间扫描与 to_string 规范
c++·算法·leetcode