poj1088 dp+记忆化搜索

就是求最长下降序列,就是深搜并记录矩阵中每个地方的最长降序列。

状态转移方程为: dp[ i ][ j ] = MAX( dp[ i - 1 ][ j ] , dp[ i + 1 ][ j ], dp[ i ][ j - 1], dp[ i ][ j + 1] ) + 1;  当然写代码时要注意越界判断。

代码可能有点冗长,可以用方向数组,判断条件就不会这么麻烦了。 

#include <iostream>
using namespace std;

const int size = 102;
int map[size][size];
int dp[size][size];
int row, col, maxLen;

int getLenth(int r, int c)
{
	if(dp[r][c] > 0) // 当某一点的长度大于0,则该处被访问过,且存储的最长降序列的长度。
        return dp[r][c];

	// 当某一点无法下滑时,即到达底部,长度为1
    if( ((r > 0 && map[r-1][c] >= map[r][c]) || r == 0) && ((r < row-1 && map[r+1][c] >= map[r][c]) || r == row-1) 
		&& ((c > 0 && map[r][c-1] >= map[r][c]) || c == 0) && ((c < col-1 && map[r][c+1] >= map[r][c]) || c == col-1) )
        return (dp[r][c] = 1);

	int tmp;
    if(r > 0 && map[r-1][c] < map[r][c]) //求出四个方向的降序列的长度,dp[r][c]存储其中最长的序列
	{
		tmp = getLenth(r-1, c) + 1;
		if(tmp > dp[r][c])
			dp[r][c] = tmp;
	}
	if(r < row-1 && map[r+1][c] < map[r][c])
	{
        tmp = getLenth(r+1, c) + 1;
		if(tmp > dp[r][c])
			dp[r][c] = tmp;
	}
	if(c > 0 && map[r][c-1] < map[r][c])
	{
		tmp = getLenth(r, c-1) + 1;
		if(tmp > dp[r][c])
			dp[r][c] = tmp;
	}
	if(c < col-1 && map[r][c+1] < map[r][c])
	{
		tmp = getLenth(r, c+1) + 1;
		if(tmp > dp[r][c])
			dp[r][c] = tmp;
	}
	if(dp[r][c] > maxLen)
		maxLen = dp[r][c]; //存储得到的最长降序列长度,即题目中的答案
	return dp[r][c];
}

int main()
{
    int i, j;
    
	memset(dp, 0, sizeof(dp));
	maxLen = 1; // 初始化为1,因为降序列最短距离为1
	scanf("%d %d", &row, &col);
    for(i = 0; i < row; i++)
		for(j = 0; j < col; j++)
            scanf("%d", &map[i][j]);
	for(i = 0; i < row; i++)
		for(j = 0; j < col; j++)
			getLenth(i, j);
	printf("%d\n", maxLen);
	//system("pause");
	return 0;
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值