0
点赞
收藏
分享

微信扫一扫

[动态规划]DP11 矩阵的最小路径和-简单

​​DP11 矩阵的最小路径和​​

描述

给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。


数据范围: ,矩阵中任意值都满足 

要求:时间复杂度 


例如:当输入[[1,3,5,9],[8,1,3,4],[5,0,6,1],[8,8,4,0]]时,对应的返回值为12,

所选择的最小累加和路径如下图所示:

[动态规划]DP11 矩阵的最小路径和-简单_动态规划_04

输入描述:

第一行输入两个正整数 n 和 m 表示矩阵 a 的长宽

后续输入 n 行每行有 m 个数表示矩阵的每个元素

输出描述:

输出从左上角到右下角的最小路径和

示例1

输入:

4 4
1 3 5 9
8 1 3 4
5 0 6 1
8 8 4 0

复制

输出:

12

复制

示例2

输入:

2 3
1 2 3
1 2 3

复制

输出:

7

题解

题目很简单,定义个矩阵作为dp[i][k]表示从(0,0)到达(i,k)的最小路径和。则:

  • dp[0][k] = dp[0][k-1]+v[0][k]
  • dp[i][0] = dp[i-1][0] + v[i][0]
  • dp[i][k] = min(dp[i-1][k],dp[i][k-1]) + v[i][k]

代码如下:

#include <bits/stdc++.h>

using namespace std;

int main()
{
int m, n;
std::cin >> m >> n;
std::vector<std::vector<int>> v(m, std::vector<int>(n, 0));
int x = m * n;
int i = 0;
while (i < x)
{
std::cin >> v[i / n][i % n];
i++;
}

std::vector<std::vector<int>> dp(m, std::vector<int>(n, 0));
for (int i = 0; i < m; ++i)
{
for (int k = 0; k < n; ++k)
{
if (i == 0 && k == 0)
{
dp[i][k] = v[0][0];
}
else if (i == 0)
{
dp[i][k] = dp[i][k - 1] + v[i][k];
}
else if (k == 0)
{
dp[i][k] = dp[i - 1][k] + v[i][k];
}
else
{
dp[i][k] = std::min(dp[i - 1][k], dp[i][k - 1]) + v[i][k];
}
}
}
std::cout << dp[m - 1][n - 1] << std::endl;
return 0;
}


举报

相关推荐

0 条评论