c_cpp 计算网格上从左上角单元格到右下角单元格的最小成本路径

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 计算网格上从左上角单元格到右下角单元格的最小成本路径相关的知识,希望对你有一定的参考价值。

// $ g++ mincost.cpp --std=c++11
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

#undef RECURSION
#undef MEMOIZATION
#undef DYNAMIC_PROGRAMMING
#undef RUN

#define RECURSION 1
#define MEMOIZATION 2
#define DYNAMIC_PROGRAMMING 3
// #define RUN RECURSION
// #define RUN MEMOIZATION
#define RUN DYNAMIC_PROGRAMMING

#if RUN == RECURSION

int
MinCost(std::vector<std::vector<int>>& cost,
        unsigned int row, unsigned int col)
{
  assert(row < cost.size() && col < cost[row].size());

  if (row == 0 && col == 0) {
    return cost[row][col];
  } else if (row == 0) {
    return cost[row][col] + MinCost(cost, row, col-1);
  } else if (col == 0) {
    return cost[row][col] + MinCost(cost, row-1, col);
  }
  return cost[row][col] + std::min(MinCost(cost, row, col-1),
                                   MinCost(cost, row-1, col));
}

int
MinCost(std::vector<std::vector<int>>& cost)
{
  assert(cost.size());
  unsigned int rightmost = cost.size()-1;
  assert(cost[rightmost].size());
  unsigned int bottommost = cost[rightmost].size() - 1;
  return MinCost(cost, rightmost, bottommost);
}

#elif RUN == MEMOIZATION

int
MinCost(std::vector<std::vector<int>>& cost,
        unsigned int row, unsigned int col,
        std::vector<std::vector<int>>& memo)
{
  assert(row < cost.size() && col < cost[row].size() &&
         memo.size() == cost.size() && memo[row].size() == cost[row].size());

  if (!memo[row][col]) {
    if (row == 0 && col == 0) {
      memo[row][col] = cost[row][col];
    } else if (row == 0) {
      memo[row][col] = cost[row][col] + MinCost(cost, row, col-1, memo);
    } else if (col == 0) {
      memo[row][col] = cost[row][col] + MinCost(cost, row-1, col, memo);
    } else {
      memo[row][col] = cost[row][col] +
                       std::min(MinCost(cost, row, col-1, memo),
                                MinCost(cost, row-1, col, memo));
    }
  }

  return memo[row][col];
}

int
MinCost(std::vector<std::vector<int>>& cost)
{
  assert(cost.size());
  unsigned int rightmost = cost.size()-1;
  assert(cost[rightmost].size());
  unsigned int bottommost = cost[rightmost].size() - 1;

  std::vector<std::vector<int>>
    memo (cost.size(), std::vector<int>(cost[rightmost].size(), 0));

  return MinCost(cost, rightmost, bottommost, memo);
}

#else // RUN == DYNAMIC_PROGRAMMING

int
MinCost(std::vector<std::vector<int>>& cost)
{
  assert(cost.size() && cost[0].size());

  unsigned int rightmost = cost.size()-1;
  unsigned int bottommost = cost[rightmost].size() - 1;

  unsigned int sum = 0;
  unsigned int x = 0, y = 0; // Starting cell.

  // Find the minimal cost path from top-left cell to the bottom-right cell.
  while (true) {
    sum += cost[x][y];
    if (x == rightmost && y == bottommost) {
      break;
    } else if (x == rightmost) {
      ++y;

    } else if (y == bottommost) {
      ++x;
    } else {
      if (cost[x+1][y] < cost[x][y+1]) {
        ++x;
      } else {
        ++y;
      }
    }
  }

  return sum;
}

#endif

int main()
{
  // Calculate the minimal cost path from the top-left cell
  // to the bottom-right cell on a grid.
  std::vector<std::vector<int>> cost {
    { 1, 3, 5, 8 },
    { 4, 2, 1, 7 },
    { 4, 3, 2, 3 }
  };

  std::cout << MinCost(cost) << std::endl;

  return 0;
}

以上是关于c_cpp 计算网格上从左上角单元格到右下角单元格的最小成本路径的主要内容,如果未能解决你的问题,请参考以下文章

tvOS tableView 从一个单元格到另一个单元格平滑滚动

选择从第一个单元格到列中使用的最后一个单元格的范围

具有多个文本字段的多个单元格到核心数据属性

Excel 单元格到 ADODB.Recordset

如何动态添加单元格到UICollectionView

Office_Execl