Last active
February 5, 2018 05:29
-
-
Save ChunMinChang/6ab89214a1a6818e46d3442c74516ab8 to your computer and use it in GitHub Desktop.
Calculate the minimal cost path from the top-left cell to the bottom-right cell on a grid #recursion #dynamic_programming #DPfCI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// $ 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment