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];
    }
};
相关推荐
宵时待雨6 分钟前
C++笔记归纳13:map & set
开发语言·数据结构·c++·笔记·算法
1104.北光c°1 小时前
滑动窗口HotKey探测机制:让你的缓存TTL更智能
java·开发语言·笔记·程序人生·算法·滑动窗口·hotkey
仰泳的熊猫5 小时前
题目2570:蓝桥杯2020年第十一届省赛真题-成绩分析
数据结构·c++·算法·蓝桥杯
无极低码8 小时前
ecGlypher新手安装分步指南(标准化流程)
人工智能·算法·自然语言处理·大模型·rag
软件算法开发9 小时前
基于海象优化算法的LSTM网络模型(WOA-LSTM)的一维时间序列预测matlab仿真
算法·matlab·lstm·一维时间序列预测·woa-lstm·海象优化
罗超驿9 小时前
独立实现双向链表_LinkedList
java·数据结构·链表·linkedlist
superior tigre9 小时前
22 括号生成
算法·深度优先
努力也学不会java11 小时前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
旖-旎11 小时前
二分查找(x的平方根)(4)
c++·算法·二分查找·力扣·双指针