格子取数问题的动态规划和递归解法之比较

本文探讨了一个n*n格子的取数问题,要求从左上角到右下角走两次,每次只能向下或向右,经过的格子数值累加,但同一格子只计一次。文章提供了单次路径的最大和的递归与动态规划解法,以及两次不同路径的递归解法,旨在比较不同解法的效率和思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 题目详情

有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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值