您的位置:首页 > 其它

poj 1088 滑雪

2010-08-27 19:11 417 查看
//如果这道题用暴力搜索,可以AC,但要花四百多ms
#include <cstdio>

int height[110][110];
int wt[110][110];

int main()
{
int r,c;
int sum=0,minx=0,miny=0;
scanf("%d%d",&r,&c);
for (int i=0;i<r;i++)
for (int j=0;j<c;j++)
{
scanf("%d",&height[i][j]);
if (height[i][j]<height[minx][miny])
{ minx=i; miny=j; }
wt[i][j]=1;
}
int w;
int p,h,vx,vy;
int flag=1;
while (flag)
{
flag=0;

for (vx=0;vx<r;vx++)
for (vy=0;vy<c;vy++)
{

p=vx-1;
w=wt[vx][vy];h=height[vx][vy];
if (p>=0 && height[p][vy]>h)
if (w+1>wt[p][vy])
{ flag=1;wt[p][vy]=w+1; }
p=vx+1;
if (p<r && height[p][vy]>h)
if (w+1>wt[p][vy])
{ flag=1;wt[p][vy]=w+1; }
p=vy-1;
if (p>=0 && height[vx][p]>h)
if (w+1>wt[vx][p])
{ flag=1;wt[vx][p]=w+1; }
p=vy+1;
if (p<c && height[vx][p]>h)
if (w+1>wt[vx][p])
{ flag=1; wt[vx][p]=w+1; }
}
}

for (int i=0; i<r;i++)
for (int j=0;j<c;j++)
if (wt[i][j]>sum)
sum=wt[i][j];
printf("%d/n",sum);

return 0;
}

//这是记忆搜索的方法,几乎0ms!

#include <cstdio>

int height[102][102]; //高度
int wt[102][102]; //记录各点到达的最长长度
int r,c; //行数和列数

int DP(int i,int j)
{
if (wt[i][j])
return wt[i][j]; //如果已经递归过,长度值就不为初始值(0)了,避免重复运算
int max=0;
int p,h=height[i][j]; //利用递归找到邻近点中长度最长的
if ((p=i-1)>=0 && height[p][j]<h)
if ( DP(p,j)>max)
max=DP(p,j);
if ((p=i+1)<r && height[p][j]<h)
if (DP(p,j)>max)
max=DP(p,j);
if ((p=j-1)>=0 && height[i][p]<h)
if (DP(i,p)>max)
max=DP(i,p);
if ((p=j+1)<c && height[i][p]<h)
if (DP(i,p)>max)
max=DP(i,p);
wt[i][j]=max+1; //使用了一个技巧,如果四个更新后max仍为0,会被赋以初始值1
return wt[i][j];
}

int main()
{
scanf ("%d%d",&r,&c);
int max=0;
for (int i=0;i<r;++i)
for (int j=0;j<c;++j)
{
scanf("%d",&height[i][j]);
wt[i][j]=0;
}
for (int i=0;i<r;++i)
for (int j=0;j<c;++j)
if (DP(i,j)>max)
max=DP(i,j);
printf("%d/n",max);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: