• 2304. 网格中的最小路径代价-297地平线周赛回顾


     有一说一,如果这道题用dfs不会报超时错误的话,对我来说还是比较简单的,但事与愿违,dfs确实不好做这道题,计算量太大,很容易超时。

    当然,凡是能用dfs做的且超时,用dp做基本都能解,可能我个人对dp不是很熟练,所以写起来有点磕磕绊绊。

    思路:

    dp数组的意义还是很好理解的,就是第1行到 第 i 行 第 j 列所用的最小代价。

    ps:这里难就难在路径太多,数值太多,让人有点晕- -

    动规五部曲:

    1.dp数组---含义见上;

    2.初始化----显然第一行到自己这一行的代价是它本身;

    3.递推公式:重点!!!

    dp[i][j]----表示到 第 i 行 第 j 列的最小值;则该值由两个方向可以得到,一个是选择当前节点作为路径节点加入到路径中,另一个就是不选择当且节点为路径节点,而是沿用之前选择过的结点。两者作比较,选择最小的。

    dp[i][j]=min(dp[i][j],dp[i-1][j]+moveCost[grid[i-1][k]][j]+grid[i][j]);

     注意:此时有三层循环 i j 表示当前 行列,k代表上一轮选择的列

    1. class Solution {
    2. public:
    3. int res=INT_MAX;
    4. int minPathCost(vector<vector<int>>& grid, vector<vector<int>>& moveCost) {
    5. //dp[i][j] 数组的含义:第一行 到 第 i 行 第 j 列花费的最小代价
    6. vector<vector<int>>dp(grid.size(),vector<int>(grid[0].size(),INT_MAX));
    7. //初始化
    8. for (int j = 0; j < grid[0].size(); j++)dp[0][j] = grid[0][j];
    9. //递推公式
    10. //dp[i][j] = min(dp[i][j], dp[i-1][j] +moveCost[grid[i-1][j]][j]);
    11. //遍历顺序 从前到后
    12. for (int i = 1; i < grid.size(); i++)
    13. {
    14. for (int j = 0; j < grid[i].size(); j++) //表示 一个结点
    15. {
    16. for (int k = 0; k < grid[i].size(); k++) //表示结点所在列
    17. {
    18. dp[i][j] = min(dp[i][j], dp[i - 1][k] + moveCost[grid[i - 1][k]][j] + grid[i][j]);
    19. }
    20. }
    21. }
    22. for (int j = 0; j < grid[0].size(); j++)
    23. res = min(res, dp[grid.size() - 1][j]);
    24. return res;
    25. //打印dp
    26. }
    27. };

    ————————————————此处可不看————————————————————— 

    也让我沾一下我的dfs吧,花了老鼻子劲写的,除了数据大跑不动以外,小数据量还是对的,让它见见外面的世界 ~

    1. #include<iostream>
    2. #include<vector>
    3. #include<algorithm>
    4. using namespace std;
    5. int result_1 = 0;
    6. int result_2 = 0;
    7. int result;
    8. int minnum = INT_MAX;
    9. void dfs(vector<vector<int>>& grid, vector<vector<int>>& moveCost, int p_val, vector<int>& v, int x, int y)
    10. {
    11. if (x == grid.size() - 1&&v.size()==grid.size())
    12. {
    13. result = result_1 + result_2;
    14. minnum = minnum > result ? result : minnum;
    15. return;
    16. }
    17. for (int i = x + 1; i < grid.size(); i++){
    18. for (int j = 0; j < grid[0].size(); j++)
    19. {
    20. result_1 += moveCost[p_val][j];
    21. result_2 += grid[i][j];
    22. v.push_back(p_val);
    23. dfs(grid, moveCost, grid[i][j], v, i, j);
    24. v.pop_back();
    25. // result -= (grid[i][j]+ moveCost[p_val][j]);
    26. result_2 -= grid[i][j];
    27. result_1 -= moveCost[p_val][j];
    28. }
    29. }
    30. return;
    31. }
    32. int minPathCost(vector<vector<int>>& grid, vector<vector<int>>& moveCost) {
    33. vector<int>v;
    34. for (int i = 0; i < grid[0].size(); i++)
    35. {
    36. result_2 += grid[0][i];
    37. v.push_back(grid[0][i]);
    38. dfs(grid, moveCost, grid[0][i], v, 0, i);
    39. v.pop_back();
    40. result_2 -= grid[0][i];
    41. }
    42. return minnum;
    43. }
    44. int main()
    45. {
    46. int g_row, g_col, c_row, c_col;
    47. cin >> g_row >> g_col >> c_row >> c_col;
    48. vector<vector<int>>grid(g_row, vector<int>(g_col, 0));
    49. vector<vector<int>>moveCost(c_row, vector<int>(c_col, 0));
    50. for (int i = 0; i < g_row; i++)
    51. {
    52. for (int j = 0; j < g_col; j++)
    53. {
    54. cin >> grid[i][j];
    55. }
    56. }
    57. for (int i = 0; i < c_row; i++)
    58. {
    59. for (int j = 0; j < c_col; j++)
    60. {
    61. cin >> moveCost[i][j];
    62. }
    63. }
    64. minPathCost(grid, moveCost);
    65. cout << minnum;
    66. return 0;

    动规得努力啊!!!!

  • 相关阅读:
    文件操作--I/O
    JS模块化系统
    吃柿子的禁忌靠谱吗?
    第八章——权限管理与备份
    初阶C语言 - 分支语句(if、switch)
    day36-单元测试
    leetcode_力扣_1640. 能否连接形成数组
    SonarQube的使用心得
    动态盘转换为基本盘
    Springboot01入门
  • 原文地址:https://blog.csdn.net/qq_57328462/article/details/125451583