【动态规划】【矩阵】C++算法329矩阵中的最长递增路径

简介: 【动态规划】【矩阵】C++算法329矩阵中的最长递增路径

作者推荐

视频算法专题

本文涉及知识点

动态规划汇总

题目

给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度。

对于每个单元格,你可以往上,下,左,右四个方向移动。 你 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)。

示例 1:

输入:matrix = [[9,9,4],[6,6,8],[2,1,1]]

输出:4

解释:最长递增路径为 [1, 2, 6, 9]。

示例 2:

输入:matrix = [[3,4,5],[3,2,6],[2,2,1]]

输出:4

解释:最长递增路径是 [3, 4, 5, 6]。注意不允许在对角线方向上移动。

示例 3:

输入:matrix = [[1]]

输出:1

提示:

m == matrix.length

n == matrix[i].length

1 <= m, n <= 200

0 <= matrix[i][j] <= 231 - 1

动态规划

时间复杂度: O(nmlog(nm))。

一,将行列压缩成一维。m_c*r+c。

二,建立图论的临接表。两个节点4连接,值小的指向值大的。

三,从值大的到值小的动态规划。

动态规划的细节,方便检查

动态规划的状态表示 dp[i]记录当前节点为起点的最长路径长度
动态规划的转移方程 1+ max(dp[j]) j 是邻接表的节点
动态规划的初始状态 无需初始化,所有节点都会处理。
动态规划的填表顺序 从值大到值小处理,,确保动态规划的无后效性
动态规划的返回值 dp的最大值

注意:最小值不一定是最大长度。比如:

1 9 2
9 4 3

1只能1->9

2可以2->3->4

代码

核心代码

class CEnumGridEdge
{
public:
  void Init()
  {
    for (int r = 0; r < m_r; r++)
    {
      for (int c = 0; c < m_c; c++)
      {
        Move(r, c, r + 1, c);
        Move(r, c, r - 1, c);
        Move(r, c, r, c + 1);
        Move(r, c, r, c - 1);
      }
    }
  }
protected:
  CEnumGridEdge(int r, int c) :m_r(r), m_c(c)
  {
    
  }
  void Move(int preR, int preC, int r, int c)
  {
    if ((r < 0) || (r >= m_r))
    {
      return;
    }
    if ((c < 0) || (c >= m_c))
    {
      return;
    }
    OnEnumEdge(preR, preC, r, c);
  };
  virtual void OnEnumEdge(int preR, int preC, int r, int c) = 0;
const int m_r, m_c;
};
class CMatToNeibo : public CEnumGridEdge
{
public:
  CMatToNeibo(const vector<vector<int>>& matrix) :CEnumGridEdge(matrix.size(), matrix[0].size()), m_mat(matrix), m_NodeCount(m_r* m_c), m_vNeiBo(m_NodeCount)
  {
    for (int r = 0; r < m_r; r++)
    {
      for (int c = 0; c < m_c; c++)
      {
        m_mValueToIndex.emplace(matrix[r][c], m_c * r + c);
      }
    }
  }
  int Do()
  {
    Init();
    vector<int> dp(m_NodeCount);
    for (const auto& [_tmp, inx] : m_mValueToIndex)
    {
      int iMax = 0;
      for (const auto& next : m_vNeiBo[inx])
      {
        iMax = max(iMax, dp[next]);
      }
      dp[inx] = iMax + 1;
    }
    return *std::max_element(dp.begin(),dp.end());
  }
  const int m_NodeCount;
  vector<vector<int>> m_vNeiBo;
  const vector<vector<int>>& m_mat;
  std::multimap<int, int, greater<>> m_mValueToIndex;
protected:
  virtual void OnEnumEdge(int preR, int preC, int r, int c)
  {
    if (m_mat[preR][preC] < m_mat[r][c])
    {
      m_vNeiBo[m_c * preR + preC].emplace_back(m_c * r + c);
    }
  }
};
class Solution {
public:
  int longestIncreasingPath(vector<vector<int>>& matrix) {
    CMatToNeibo mn(matrix);
    return mn.Do();
  }
};

2023年1月

class Solution {

public:

int longestIncreasingPath(vector<vector>& matrix) {

m_r = matrix.size();

m_c = matrix[0].size();

m_dp.assign(m_r, vector(m_c, -1));

std::map<int,vector<pair<int,int>>> mVRC;

for (int r = 0; r < m_r; r++)

{

for (int c = 0; c < m_c; c++)

{

mVRC[matrix[r][c]].emplace_back(r, c);

}

}

for (auto& it : mVRC)

{

for (auto& rc : it.second)

{

m_dp[rc.first][rc.second] = Test(matrix, rc.first, rc.second);

}

}

int iMax = 0;

for (int r = 0; r < m_r; r++)

{

for (int c = 0; c < m_c; c++)

{

iMax = max(iMax, m_dp[r][c]);

}

}

return iMax;

}

int Test(const vector<vector>& matrix,int r, int c)

{

int iMax = 0;

if ((r > 0) && (matrix[r][c] > matrix[r - 1][c]))

{

iMax = max(iMax,m_dp[r-1][c] );

}

if ((r +1 < m_r ) && (matrix[r][c] > matrix[r + 1][c]))

{

iMax = max(iMax, m_dp[r + 1][c]);

}

if ((c > 0) && (matrix[r][c] > matrix[r][c-1]))

{

iMax = max(iMax, m_dp[r][c-1]);

}

if ((c + 1 < m_c) && (matrix[r][c] > matrix[r][c + 1]))

{

iMax = max(iMax, m_dp[r][c + 1]);

}

return iMax + 1;

}

int m_r;

int m_c;

vector<vector> m_dp;

};

2023年8月

class Solution {

public:

int longestIncreasingPath(vector<vector>& matrix) {

m_r = matrix.size();

m_c = matrix.front().size();

m_iMaskNum = m_r * m_c;

//生成邻接表

vector<vector> vNeiBo(m_iMaskNum);

vector vInDeg(m_iMaskNum);

for (int r = 0; r < m_r; r++)

{

for (int c = 0; c < m_c; c++)

{

auto Add = [this,&matrix, &vNeiBo,&vInDeg](int curMask, int curValue, int r, int c)

{

if ((r < 0) || (r >= m_r))

{

return;

}

if ((c < 0) || (c >= m_c))

{

return;

}

if (curValue > matrix[r][c])

{

vNeiBo[r * m_c + c].emplace_back(curMask);

vInDeg[curMask]++;

}

};

Add(r * m_c + c, matrix[r][c], r + 1, c);

Add(r * m_c + c, matrix[r][c], r - 1, c);

Add(r * m_c + c, matrix[r][c], r, c + 1);

Add(r * m_c + c, matrix[r][c], r, c - 1);

}

}

//top排序

queue que;

vector vLen(m_iMaskNum, 0);

for (int i = 0; i < m_iMaskNum; i++)

{

if (0 == vInDeg[i])

{

que.emplace(i);

vLen[i] = 1;

}

}

while (que.size())

{

const int cur = que.front();

que.pop();

for (const auto& next : vNeiBo[cur])

{

if (–vInDeg[next] == 0)

{

vLen[next] = vLen[cur] + 1;

que.emplace(next);

}

}

}

return *std::max_element(vLen.begin(), vLen.end());

}

int m_r;

int m_c;

int m_iMaskNum;

};


目录
打赏
0
1
1
0
36
分享
相关文章
|
9天前
|
算法系列之动态规划
动态规划(Dynamic Programming,简称DP)是一种用于解决复杂问题的算法设计技术。它通过将问题分解为更小的子问题,并存储这些子问题的解来避免重复计算,从而提高算法的效率。
22 4
算法系列之动态规划
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
31 15
公司局域网管理中的哈希表查找优化 C++ 算法探究
在数字化办公环境中,公司局域网管理至关重要。哈希表作为一种高效的数据结构,通过哈希函数将关键值(如IP地址、账号)映射到数组索引,实现快速的插入、删除与查找操作。例如,在员工登录验证和设备信息管理中,哈希表能显著提升效率,避免传统线性查找的低效问题。本文以C++为例,展示了哈希表在局域网管理中的具体应用,包括设备MAC地址与IP分配的存储与查询,并探讨了优化哈希函数和扩容策略,确保网络管理高效准确。
|
11天前
|
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
在数字化办公时代,公司监控上网软件成为企业管理网络资源和保障信息安全的关键工具。本文深入剖析C++中的链表数据结构及其在该软件中的应用。链表通过节点存储网络访问记录,具备高效插入、删除操作及节省内存的优势,助力企业实时追踪员工上网行为,提升运营效率并降低安全风险。示例代码展示了如何用C++实现链表记录上网行为,并模拟发送至服务器。链表为公司监控上网软件提供了灵活高效的数据管理方式,但实际开发还需考虑安全性、隐私保护等多方面因素。
17 0
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
本研究基于MATLAB 2022a,使用GRU网络对QAM调制信号进行检测。QAM是一种高效调制技术,广泛应用于现代通信系统。传统方法在复杂环境下性能下降,而GRU通过门控机制有效提取时间序列特征,实现16QAM、32QAM、64QAM、128QAM的准确检测。仿真结果显示,GRU在低SNR下表现优异,且训练速度快,参数少。核心程序包括模型预测、误检率和漏检率计算,并绘制准确率图。
83 65
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
基于PSO粒子群优化的CNN-LSTM-SAM网络时间序列回归预测算法matlab仿真
本项目展示了基于PSO优化的CNN-LSTM-SAM网络时间序列预测算法。使用Matlab2022a开发,完整代码含中文注释及操作视频。算法结合卷积层提取局部特征、LSTM处理长期依赖、自注意力机制捕捉全局特征,通过粒子群优化提升预测精度。适用于金融市场、气象预报等领域,提供高效准确的预测结果。
基于Big-Bang-Big-Crunch(BBBC)算法的目标函数最小值计算matlab仿真
该程序基于Big-Bang-Big-Crunch (BBBC)算法,在MATLAB2022A中实现目标函数最小值的计算与仿真。通过模拟宇宙大爆炸和大收缩过程,算法在解空间中搜索最优解。程序初始化随机解集,经过扩张和收缩阶段逐步逼近全局最优解,并记录每次迭代的最佳适应度。最终输出最佳解及其对应的目标函数最小值,并绘制收敛曲线展示优化过程。 核心代码实现了主循环、粒子位置更新、适应度评估及最优解更新等功能。程序运行后无水印,提供清晰的结果展示。
|
18天前
|
基于遗传优化算法的风力机位置布局matlab仿真
本项目基于遗传优化算法(GA)进行风力机位置布局的MATLAB仿真,旨在最大化风场发电效率。使用MATLAB2022A版本运行,核心代码通过迭代选择、交叉、变异等操作优化风力机布局。输出包括优化收敛曲线和最佳布局图。遗传算法模拟生物进化机制,通过初始化、选择、交叉、变异和精英保留等步骤,在复杂约束条件下找到最优布局方案,提升风场整体能源产出效率。
基于CS模型和CV模型的多目标协同滤波跟踪算法matlab仿真
本项目基于CS模型和CV模型的多目标协同滤波跟踪算法,旨在提高复杂场景下多个移动目标的跟踪精度和鲁棒性。通过融合目标间的关系和数据关联性,优化跟踪结果。程序在MATLAB2022A上运行,展示了真实轨迹与滤波轨迹的对比、位置及速度误差均值和均方误差等关键指标。核心代码包括对目标轨迹、速度及误差的详细绘图分析,验证了算法的有效性。该算法结合CS模型的初步聚类和CV模型的投票机制,增强了目标状态估计的准确性,尤其适用于遮挡、重叠和快速运动等复杂场景。
基于Adaboost的数据分类算法matlab仿真
本程序基于Adaboost算法进行数据分类的Matlab仿真,对比线性与非线性分类效果。使用MATLAB2022A版本运行,展示完整无水印结果。AdaBoost通过迭代训练弱分类器并赋予错分样本更高权重,最终组合成强分类器,显著提升预测准确率。随着弱分类器数量增加,训练误差逐渐减小。核心代码实现详细,适合研究和教学使用。