格子取數問題的動態規劃和遞歸解法之比較

 題目詳情

有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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章