1. 程式人生 > 其它 >P1434 [SHOI2002]滑雪【記搜】

P1434 [SHOI2002]滑雪【記搜】

洛谷 P1434 -> Click Here

題意

一個二位矩陣,在一個點可向上下左右移動,如果目標點的高度嚴格小於當前點的高度,問做多可以移動多少次

思路

記搜入門題

相當於求二維的最長下降數列,使用記憶化搜尋,記 $f[y][x] $​ 為從點 \((y,x)\)​ 出發最大的移動次數, \(A[y][x]\)​ 為點 \((y,x)\)​​​ 的高度,遞迴每一個點,得出最大值

code

#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
int A[105][105];
int f[105][105];
int vis[105][105];
int uy[]={0,1,0,-1};
int ux[]={1,0,-1,0};
bool pan(int y,int x){
	if(y>=1&&y<=n&&x>=1&&x<=m) return true;
	return false;
}
int ans;
int go(int y,int x){
	if(vis[y][x]==1) return f[y][x];
	vis[y][x]=1;
	f[y][x]=1;
	for(int i=0;i<4;i++)
		if(pan(y+uy[i],x+ux[i])&&A[y][x]>A[y+uy[i]][x+ux[i]])
			f[y][x]=max(f[y][x],1+go(y+uy[i],x+ux[i]));
	return f[y][x];
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&A[i][j]);
	int ans=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			ans=max(ans,go(i,j));
	printf("%d\n",ans);
	return 0;
}