什么情况下,使用记忆化搜索比动态规划更加方便???

动态规划是自底向上的,先处理子问题,然后再处理更大的问题。这样就需要知道子问题和更大的问题之间的联系。我们能够确定出子问题并且能够正确的求解它,从而从子问题推出要解决的问题的解。

但是,如果当我们比较难确定出子问题是哪一个,比较困难的求出子问题的答案时,可以使用记忆化搜索

以洛谷上的滑雪题为例

对于这道题,我们没办法马上求得到达某个点的最长长度

因此我们需要使用递归方法,并且使用记忆化搜索来进行优化

思路

使用递归计算出,到x,y点的最长滑坡长度 

遍历点(x,y)的上下左右四个点,如果一个点的值是小于点(x,y),说明这个点可以滑到点(x,y)

答案为,四个点中最长滑坡长度的最大值+1

res = max(res,getMax(newx,newy)+1);

使用循环更新数组的值,直到数组所有的值都被更新,找到数组中最大的那个值

代码

#include <iostream>
#include <vector>
using namespace std;
/**
输入 
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
输出 
25
*/

int memo[105][105];
int quyu[105][105];
int R,C;
bool inArea(int x, int y )
{
	return x>=1 && y>=1 && x<=R && y<=C;
}
//到x,y点的最长滑坡长度 
int d[4][2] ={0,-1,1,0,-1,0,0,1};
int getMax(int x,int y)
{
	//上下左右四个点中可达该点的数
	if(memo[x][y]!=-1) return memo[x][y];
	int res = 1; 
	for(int i=0; i<4; i++)
	{
		int newx = x+d[i][0];
		int newy = y+d[i][1];
		if(inArea(newx,newy) && quyu[x][y]>quyu[newx][newy]) 
		{
			res = max(res,getMax(newx,newy)+1);
		}
	}
	memo[x][y] = res;
	return res;	 
}
int main()
{
	cin>>R>>C;
	for(int i=1; i<=R; i++)
	{
		for(int j=1; j<=C; j++)
			cin>>quyu[i][j];
	}
	int res = 0; 
	for(int i=0; i<105; i++)
		for(int j=0; j<105; j++)
			memo[i][j]=-1;
			
	for(int i=1; i<=R; i++)
	{
		for(int j=1; j<=C; j++)
		{
			if(memo[i][j]==-1)
				res=max(res,getMax(i,j));
			else
				res=max(res,memo[i][j]);
		}
	}
	cout<<res<<endl;
	
	return 0;
} 

 

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