PKU 1088 滑雪

这题的思路就是遍历所有格子,如果这个格子的周围有比他小的,那么她的最大长度就是周围最大的长度+1和自己比较,取较大的,但是要进行深搜,因为后面没有遍历到的格子他的最大长度还不知道呢,需要记忆化搜索,也就是要把最大长度保存起来,否则会超时哦!

#include<iostream>
#include <algorithm>
using namespace std;
int r,c;
int num[101][101];//保存每个格子的数
int best[101][101];//保存最大长度
int dx[4]={-1,0,0,1};//这两个数组用来移动至上下左右
int dy[4]={0,1,-1,0};
int dp(int a,int b)
{
    if(best[a][b]>1)return best[a][b];//如果以前已经计算过了就直接返回那个值
    for(int k=0;k<4;k++)
        if(a+dx[k]>=1&&a+dx[k]<=r&&b+dy[k]>=1&&b+dy[k]<=c&&num[a+dx[k]][b+dy[k]]<num[a][b])//如果在范围内,并且数字比自己小的话
            best[a][b]=max(best[a][b],dp(a+dx[k],b+dy[k])+1);//周围最大的长度+1和自己比较,取较大的,这里用了函数dp,实际上是进行深搜了,这样才能保证周围的长度都是正确的
    return best[a][b];
}
int main()
{
    cin>>r>>c;
    for(int i=1;i<=r;i++)
        for(int j=1;j<=c;j++)
            cin>>num[i][j];
    for(int i=1;i<=r;i++)
        for(int j=1;j<=c;j++)
            best[i][j]=1;
    int max=0;
    for(int i=1;i<=r;i++)
        for(int j=1;j<=c;j++)
            if(dp(i,j)>max)
                max=dp(i,j);
    cout<<max<<endl;
}

http://mhxyzhengcheng.blog.163.com/blog/static/121764471201015114616288/

转自:http://mhxyzhengcheng.blog.163.com/blog/static/121764471201015114616288/

 

 

PKU 1088 滑雪 —— DFS暴力能也能达到150ms,常规DP或记忆化搜索都能0ms. 我是用常规的DP,先用sort,然后按高度递推,具体见程序。

程序清单:

#include<iostream>

#include<algorithm>

using namespace std;

#define MAXN 100

const int move[4][2]={{0,1},{0,-1},{1,0},{-1,0}};

int h[MAXN][MAXN],lp[MAXN][MAXN];

struct s

{

       int x,y,h;

}a[MAXN*MAXN];

bool cmp(s a,s b)

{

       return a.h<b.h;

}

int main()

{

       int i,j,k,r,c,x,y,ans;

       for (k=i=0,scanf("%d%d",&r,&c);i<r;++i)

              for (j=0;j<c;++j)

              {

                     scanf("%d",&h[i][j]);

                     a[k].x=i;

                     a[k].y=j;

                     a[k++].h=h[i][j];

              }

       sort(a,a+k,cmp);

       memset(lp,0,i*j*4);

       ans=0;

       for (i=0;i<k;++i)

       {

              for (j=0;j<4;++j)

              {

                     x=a[i].x+move[j][0];

                     y=a[i].y+move[j][1];

                     if (x>=0&&x<r&&y>=0&&y<c&&h[x][y]<a[i].h&&lp[a[i].x][a[i].y]<=lp[x][y])

                            lp[a[i].x][a[i].y]=lp[x][y]+1;

              }

              if (ans<=lp[a[i].x][a[i].y])

                     ans=lp[a[i].x][a[i].y];

       }

       printf("%d/n",ans+1);

       return 0;

}

转自: http://hi.baidu.com/wuxyy/blog/item/876f5143778efa109313c6b1.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值