poj 1088 滑雪--DP or 深搜?

#include<stdio.h>
#include<string.h>
int map[110][110],step[110][110];
int r,c;
int dfs(int i,int j)
{
	if(step[i][j]!=0)
		return step[i][j];
	int max=0,zmax;
	if(j-1>0&&map[i][j-1]<map[i][j])
	{
		zmax=dfs(i,j-1);
		if(zmax>max)
			max=zmax;
	}
	if(j+1<=c&&map[i][j+1]<map[i][j])
	{
		zmax=dfs(i,j+1);
		if(zmax>max)
			max=zmax;
	}
	if(i-1>0&&map[i-1][j]<map[i][j])
	{
		zmax=dfs(i-1,j);
		if(zmax>max)
			max=zmax;
	}
	if(i+1<=r&&map[i+1][j]<map[i][j])
	{
		zmax=dfs(i+1,j);
		if(zmax>max)
			max=zmax;
	}
	step[i][j]=max+1;
	return step[i][j];
}
int main()
{
	int i,j;
	scanf("%d%d",&r,&c);
	for(i=1;i<=r;i++)
		for(j=1;j<=c;j++)
			scanf("%d",&map[i][j]);
	memset(step,0,sizeof(step));
	for(i=1;i<=r;i++)
		for(j=1;j<=c;j++)
			step[i][j]=dfs(i,j);
	for(i=1;i<=r;i++)
		for(j=1;j<=c;j++)
			if(step[i][j]>step[1][1])
				step[1][1]=step[i][j];
	printf("%d\n",step[1][1]);
	return 0;
}
/*
算法:开一个二维数组height记录每个点的高度,一个二维数组len记录每个点能搜索到的最长下降子序列的长度(初始值全为零),一个结构体数组dot line[20000]记录每个点的坐标(x,y)和高度值 h.
先将每个点的记录信息保存在结构体数组中。然后以高度由低到高的顺序排序,初始状态下指针就位于结构体数组的起始位置。
接着顺序的扫描此结构体数组内的信息,因为已经排好序,所以高度是一次递增的,这样做的好处是只需要朝着一个方向搜索,而且还可以有效避免越界的问题。
当指针每指向一个结构体个体时,我们均可以找到该点在height数组里的位置,如果存在任意一个点,在它周围的四个方向上而且高度比该点大且这个任意点的最长下降子序列小于或等于该店的长度。
那么这个任意点的最长下降子序列的长度就+1;等到结构体数组扫描完成,再去遍历len这个二维数组,求出最大值即为所求;
*/
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
struct dot//创建一个结构体存储每个点的信息
{
    int x;
    int y;
    int h;
};
dot line[20000]; //将每个点存入该结构体数组
int height[120][120]; //用于存储input
int len[120][120]; //dp数组,存储每个点的最优解
int cmp( const void *a ,const void *b) //快速排序的参考函数
{
    if((*(dot *)a).h>(*(dot *)b).h)
        return 1;
    else return -1;
}
int main ()
{
	int m,n;
    cin>>m>>n;
    int i,j;
    int flag=-1;
    int max=0;
    for(i=1;i<=m;i++)
    {
        for(j=1;j<=n;j++)
        {
            flag++;
            scanf("%d",&height[i][j]);
            line[flag].x=i;
            line[flag].y=j;
            line[flag].h=height[i][j];
        }
    } //这个双层循环用来完成数据收集的工作
    qsort(line,m*n,sizeof(line[0]),cmp); //对结构体的h参数进行排序
    for(i=0;i<m*n;i++)
    {
		if(height[line[i].x][line[i].y]<height[line[i].x][line[i].y+1]&&len[line[i].x][line[i].y]>=len[line[i].x][line[i].y+1])
        {
            len[line[i].x][line[i].y+1]=len[line[i].x][line[i].y]+1;
        }
		if(height[line[i].x][line[i].y]<height[line[i].x+1][line[i].y]&&len[line[i].x][line[i].y]>=len[line[i].x+1][line[i].y])
        {
            len[line[i].x+1][line[i].y]=len[line[i].x][line[i].y]+1;
        }
		if(height[line[i].x][line[i].y]<height[line[i].x][line[i].y-1]&&len[line[i].x][line[i].y]>=len[line[i].x][line[i].y-1])
        {
            len[line[i].x][line[i].y-1]=len[line[i].x][line[i].y]+1;
        }
        if (height[line[i].x][line[i].y]<height[line[i].x-1][line[i].y]&&len[line[i].x][line[i].y]>=len[line[i].x-1][line[i].y])
        {
            len[line[i].x-1][line[i].y]=len[line[i].x][line[i].y]+1;
        }
    } //动态规划过程
    for(i=1;i<=m;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(len[i][j]>max)
                max=len[i][j];
        }
    } //遍历len数组,求出最大值
    cout<<max+1<<endl;// 因为初始值是0,所以最后要加一
    return 0;
}



 

你可能感兴趣的:(poj 1088 滑雪--DP or 深搜?)