本文概述
- C ++
- Java
注意 :
假设输入矩阵中不存在负成本周期。
这个问题是下面的问题的延伸。
最小成本路径, 允许左右移动。
在前面的问题中, 只允许向右和向下移动, 但在此问题中, 我们被允许向下, 向上, 向右和向左移动, 即沿所有四个方向移动。
例子:
A cost grid is given in below diagram, minimum
cost to reach bottom right from top left
is 327 (= 31 + 10 + 13 + 47 + 65 + 12 + 18 +
6 + 33 + 11 + 20 + 41 + 20)The chosen least cost path is shown in green.
推荐:请在"实践首先, 在继续解决方案之前。
使用类似于先前问题的动态编程无法解决此问题, 因为此处的当前状态不仅取决于右侧和底部单元, 还取决于左侧和上部单元。我们使用以下方法解决此问题:dijkstra的算法。网格的每个像元代表一个顶点, 相邻像元代表相邻的顶点。我们不会从这些单元格中生成一个明确的图形, 而是将使用dijkstra算法中的矩阵。
在下面的代码中
Dijkstra算法的实现
用来。更改以下实现的代码以应对矩阵表示的隐式图。还请参见下面的代码中dx和dy数组的使用, 这些数组用于简化访问每个像元的相邻顶点的过程。
C ++
//C++ program to get least cost path in a grid from
//top-left to bottom-right
#include <
bits/stdc++.h>
using namespace std;
#define ROW 5
#define COL 5//structure for information of each cell
struct cell
{
int x, y;
int distance;
cell( int x, int y, int distance) :
x(x), y(y), distance(distance) {}
};
//Utility method for comparing two cells
bool operator<
( const cell&
a, const cell&
b)
{
if (a.distance == b.distance)
{
if (a.x != b.x)
return (a.x <
b.x);
else
return (a.y <
b.y);
}
return (a.distance <
b.distance);
}//Utility method to check whether a point is
//inside the grid or not
bool isInsideGrid( int i, int j)
{
return (i>
= 0 &
&
i <
COL &
&
j>
= 0 &
&
j <
ROW);
}//Method returns minimum cost to reach bottom
//right from top left
int shortest( int grid[ROW][COL], int row, int col)
{
int dis[row][col];
//initializing distance array by INT_MAX
for ( int i = 0;
i <
row;
i++)
for ( int j = 0;
j <
col;
j++)
dis[i][j] = INT_MAX;
//direction arrays for simplification of getting
//neighbour
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
set<
cell>
st;
//insert (0, 0) cell with 0 distance
st.insert(cell(0, 0, 0));
//initialize distance of (0, 0) with its grid value
dis[0][0] = grid[0][0];
//loop for standard dijkstra's algorithm
while (!st.empty())
{
//get the cell with minimum distance and delete
//it from the set
cell k = *st.begin();
st.erase(st.begin());
//looping through all neighbours
for ( int i = 0;
i <
4;
i++)
{
int x = k.x + dx[i];
int y = k.y + dy[i];
//if not inside boundary, ignore them
if (!isInsideGrid(x, y))
continue ;
//If distance from current cell is smaller, then
//update distance of neighbour cell
if (dis[x][y]>
dis[k.x][k.y] + grid[x][y])
{
//If cell is already there in set, then
//remove its previous entry
if (dis[x][y] != INT_MAX)
st.erase(st.find(cell(x, y, dis[x][y])));
//update the distance and insert new updated
//cell in set
dis[x][y] = dis[k.x][k.y] + grid[x][y];
st.insert(cell(x, y, dis[x][y]));
}
}
}//uncomment below code to print distance
//of each cell from (0, 0)
/*
for (int i = 0;
i <
row;
i++, cout <
<
endl)
for (int j = 0;
j <
col;
j++)
cout <
<
dis[i][j] <
<
" ";
*/
//dis[row - 1][col - 1] will represent final
//distance of bottom right cell from top left cell
return dis[row - 1][col - 1];
}//Driver code to test above methods
int main()
{
int grid[ROW][COL] =
{
31, 100, 65, 12, 18, 10, 13, 47, 157, 6, 100, 113, 174, 11, 33, 88, 124, 41, 20, 140, 99, 32, 111, 41, 20
};
cout <
<
shortest(grid, ROW, COL) <
<
endl;
return 0;
}
Java
//Java program to get least cost path
//in a grid from top-left to bottom-right
import java.io.*;
import java.util.*;
class GFG{static int [] dx = { - 1 , 0 , 1 , 0 };
static int [] dy = { 0 , 1 , 0 , - 1 };
static int ROW = 5 ;
static int COL = 5 ;
//Custom class for representing
//row-index, column-index &
//distance of each cell
static class Cell
{
int x;
int y;
int distance;
Cell( int x, int y, int distance)
{
this .x = x;
this .y = y;
this .distance = distance;
}
}//Custom comparator for inserting cells
//into Priority Queue
static class distanceComparator
implements Comparator<
Cell>
{
public int compare(Cell a, Cell b)
{
if (a.distance <
b.distance)
{
return - 1 ;
}
else if (a.distance>
b.distance)
{
return 1 ;
}
else { return 0 ;
}
}
}//Utility method to check whether current
//cell is inside grid or not
static boolean isInsideGrid( int i, int j)
{
return (i>
= 0 &
&
i <
ROW &
&
j>
= 0 &
&
j <
COL);
}//Method to return shortest path from
//top-corner to bottom-corner in 2D grid
static int shortestPath( int [][] grid, int row, int col)
{
int [][] dist = new int [row][col];
//Initializing distance array by INT_MAX
for ( int i = 0 ;
i <
row;
i++)
{
for ( int j = 0 ;
j <
col;
j++)
{
dist[i][j] = Integer.MAX_VALUE;
}
}//Initialized source distance as
//initial grid position value
dist[ 0 ][ 0 ] = grid[ 0 ][ 0 ];
PriorityQueue<
Cell>
pq = new PriorityQueue<
Cell>
(
row * col, new distanceComparator());
//Insert source cell to priority queue
pq.add( new Cell( 0 , 0 , dist[ 0 ][ 0 ]));
while (!pq.isEmpty())
{
Cell curr = pq.poll();
for ( int i = 0 ;
i <
4 ;
i++)
{
int rows = curr.x + dx[i];
int cols = curr.y + dy[i];
if (isInsideGrid(rows, cols))
{
if (dist[rows][cols]>
dist[curr.x][curr.y] +
grid[rows][cols])
{//If Cell is already been reached once, //remove it from priority queue
if (dist[rows][cols] != Integer.MAX_VALUE)
{
Cell adj = new Cell(rows, cols, dist[rows][cols]);
pq.remove(adj);
}//Insert cell with updated distance
dist[rows][cols] = dist[curr.x][curr.y] +
grid[rows][cols];
pq.add( new Cell(rows, cols, dist[rows][cols]));
}
}
}
}
return dist[row - 1 ][col - 1 ];
}//Driver code
public static void main(String[] args)
throws IOException
{
int [][] grid = { { 31 , 100 , 65 , 12 , 18 }, { 10 , 13 , 47 , 157 , 6 }, { 100 , 113 , 174 , 11 , 33 }, { 88 , 124 , 41 , 20 , 140 }, { 99 , 32 , 111 , 41 , 20 } };
System.out.println(shortestPath(grid, ROW, COL));
}
}//This code is contributed by jigyansu
【允许向左/向右/向下和向上移动的最小成本路径】输出如下:
327
推荐阅读
- 设计和实现特殊的栈数据结构|添加了空间优化版本
- 算法题(将一个数组拆分成两个相等的和子数组)
- pe装系统图文详细教程
- 本文告诉你bios升级有啥用
- 萝卜家园win10纯净版安装图文详细教程
- 一键系统之家系统安装win7的办法
- 系统之家纯净版xp系统下载
- 系统之家与深度技术比较哪个好用
- 暴风win7 64破解激活工具运用办法