滑雪是一道dp及记忆化搜索的经典题目。
所谓记忆化搜索便是在搜索的过程中边记录边搜索的一个算法。
当下次搜到这里时,便直接使用。
而且记忆化搜索一定要满足无后效性,为什么呢,因为如果不满足无后效性的话,可能在不同的时候调用这个值所产生的结果并不同。
因此一定要满足无后效性。
且记忆化搜索一定要用深搜,因为如果广搜的话,记忆化搜索就没有什么作用了。(因为广搜一定是先搜到最优结果)
再说滑雪这道题,可以用动态规划来做,当然也可以用记忆化搜索。
可以将dp数组当作记忆化搜索的数组
在记忆化搜索中如果已经搜到这个结果,就记录,当下次搜到这个地方时,看他是否有没有被记录过,如果记录过了,直接使用就好了。
滑雪这个题的意思便是当要其余四个方向的值的高度比要当前的高度大的时候,当前高度便是那四个方向的高度的最大值+1.
最后结果是从所有的点滑雪的最大值。
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int dx[4]={-1,0,1,0}; int dy[4]={0,-1,0,1}; int map[110][110]; int dp[110][110]; int r,c; int m_search(int x,int y) { if(dp[x][y]) return dp[x][y]; int tot=1; for(int i=0;i<4;i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(map[x][y]<map[nx][ny]) { int tmp=m_search(nx,ny)+1; if(tmp>tot) tot=tmp; } } dp[x][y]=tot; return tot; } int main() { memset(map,233,sizeof(map));//一开始调为最小值 scanf("%d%d",&r,&c); for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) scanf("%d",&map[i][j]); int ans=0; for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) { dp[i][j]=m_search(i,j); ans=max(ans,dp[i][j]); } printf("%d ",ans); return 0; }