首页 > 代码库 > POJ 1088 滑雪【记忆化搜索】

POJ 1088 滑雪【记忆化搜索】

题目大意:让你找出二维数组上的最长不上升子序列

思路:曾几何时在TYVJ上写过这题!!那时觉得无从下手,如今也能半小时不看discuss写出来了,看来两年来的确有所进步

类似于一维的LIS,二维情况下f(I,j)=max(f(x,y)+1)|x,y为i,j的四个方向的拓展,直接搜显然超时,用个数组记录下f(i,j)的值也就是记忆化就可以了

#include<cstdio>

#include<string.h>

#include<iostream>

#define maxn 109

intmemory[maxn][maxn]={{0}},n,m,a[maxn][maxn]={{0}};

int max(int a,int b)

{

   if (a>b)return a;else return b;

}

int mdfs(int i,int j)

{

   int ret=0,now=a[i][j];

   if (i<1 ||j<1 ||i>m ||j>n)return -1;//边界

   if (memory[i][j]!=0)return memory[i][j];

   if (now>a[i+1][j])ret=max(mdfs(i+1,j)+1,ret);

   if (now>a[i-1][j])ret=max(mdfs(i-1,j)+1,ret);

   if (now>a[i][j+1])ret=max(mdfs(i,j+1)+1,ret);

   if (now>a[i][j-1])ret=max(mdfs(i,j-1)+1,ret);

   return memory[i][j]=ret;

}

int main()

{

   int maxi=0;

   scanf("%d%d",&m,&n);

   for(int i=1;i<=m;i++)

      for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);

   for(int i=1;i<=m;i++)

      for(int j=1;j<=n;j++)maxi=max(maxi,mdfs(i,j)+1);

   printf("%d\n",maxi);

   return 0;

}

 

my test:

5 5

1 2 3 4 5

1 2 3 4 5

1 2 3 4 5

1 2 3 4 5

1 2 3 4 5

ans:5

4 3

100 101 1 1

1 102 103 1

2 1 104 105

ans:7

调试结果:1次AC

POJ 1088 滑雪【记忆化搜索】