题目详情:
有n*n个格子,每个格子里有正数或者0,从最左上角往最右下角走,只能向下和向右,一共走两次(即从左上角走到右下角走两趟),
把所有经过 的格子的数加起来,求最大值SUM,且两次如果经过同一个格子,则最后总和SUM中该格子的计数只加一次。
解法:
下面三个程序,分别给出单条路最大和的递归和动态规划解法,以及两条路的递归解法;
代码如下:
#ifndef _MAX_PATHSUM_H_ #define _MAX_PATHSUM_H_ #include <assert.h> #define MAXARRAY_SIZE 100 typedef struct tagDirection { int stepX; int stepY; }Direction, *pDirection; /* * The solution of recursive programming for the max sum of single path * */ int FindMaxPathRecur( int grid[MAXARRAY_SIZE][MAXARRAY_SIZE], int curX, int curY, int row, int col, pDirection dir, size_t dirCount ) { if( curX == row - 1 && curY == col - 1 ) return grid[curX][curY]; int maxVal = -1; for( int i = 0; i < dirCount; i++ ) { int nextX = curX + dir[i].stepX; int nextY = curY + dir[i].stepY; if( nextX >= 0 && nextX < row && nextY >= 0 && nextY < col ) { int val = grid[curX][curY] + FindMaxPathRecur( grid, nextX, nextY, row, col, dir, dirCount ); if( maxVal < val ) maxVal = val; } } return maxVal; } /* * The solution of recursive programming for the max sum of double path * */ int FindMaxPathRecur( int grid[MAXARRAY_SIZE][MAXARRAY_SIZE], int curX1, int curY1, int curX2, int curY2, int length, int width, pDirection dir, size_t dirCount ) { if( curX1 == width - 1 && curY1 == length - 1 && curX2 == width - 1 && curY2 == length - 1 ) { return grid[length - 1][width - 1]; } int maxVal = -1; for( int i = 0; i < dirCount; i++ ) { int nextX1 = curX1 + dir[i].stepY; int nextY1 = curY1 + dir[i].stepX; if( nextX1 >= 0 && nextX1 < width && nextY1 >= 0 && nextY1 < length ) { for( int j = 0; j < dirCount; j++ ) { int nextX2 = curX2 + dir[j].stepX; int nextY2 = curY2 + dir[j].stepY; if( nextX2 >= 0 && nextX2 < width && nextY2 >= 0 && nextY2 < length ) { if( nextX1 == nextX2 && nextY1 == nextY2 ) { int val = grid[nextY1][nextX1] + FindMaxPathRecur( grid, nextX1, nextY1, nextX2, nextY2, length, width, dir, dirCount ); if( val > maxVal ) maxVal = val; } else { int val = grid[nextY1][nextX1] + grid[nextY2][nextX2] + FindMaxPathRecur( grid, nextX1, nextY1, nextX2,nextY2, length, width, dir, dirCount ); if( val > maxVal ) maxVal = val; } } } } } return maxVal; } /* * The solution of dynamic programming for the max sum of single path * */ int FindMaxPathDP( int grid[MAXARRAY_SIZE][MAXARRAY_SIZE], int row, int col, pDirection dir, size_t dirCount ) { int** table = new int*[row + 1]; assert( table ); for( int i = 0; i <= row; i++ ) { table[i] = new int[ col + 1 ]; ::memset( table[i], 0x00, sizeof(int)*(col + 1) ); assert( table[i] ); } table[0][0] = grid[0][0]; for( int i = 1; i < row; i++ ) { for( int j = 1; j < col; j++ ) { for( int k = 0; k < dirCount; k++ ) { if( 1 == dir[k].stepX && table[i-1][j-1] + grid[i][j-1] > table[i][j-1] ) { table[i][j-1] = table[i-1][j-1] + grid[i][j-1]; } else if( 1 == dir[k].stepY && table[i-1][j-1] + grid[i-1][j] > table[i-1][j] ) { table[i-1][j] = table[i-1][j-1] + grid[i-1][j]; } if( table[i][j-1] > table[i-1][j] ) { table[i][j] = table[i][j-1] + grid[i][j]; } else { table[i][j] = table[i-1][j] + grid[i][j]; } } } } int res = table[row-1][col-1]; for( int i = 0; i <= row; i++ ) { delete[] table[i]; } delete [] table; return res; } void TestFindMaxPath() { int map[MAXARRAY_SIZE][MAXARRAY_SIZE]={ {2,0,8,20,2}, {0,0,0,0,0}, {0,13,2,0,0}, {0,10,2,0,0}, {2,0,18,0,2}}; Direction dir[2] = {{0, 1}, {1, 0} }; int row = 5; int col = 5; int sval = FindMaxPathRecur( map, 0, 0, row, col, dir, 2 ); int dpVal = FindMaxPathDP( map, row, col, dir, 2 ); int dval = FindMaxPathRecur( map, 0, 0, 0, 0, row, col, dir, 2 ); } #endif