zoukankan      html  css  js  c++  java
  • POJ 1088 滑雪 (记忆化搜索)

    滑雪

    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 77134   Accepted: 28672

    Description

    Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子 
     1  2  3  4 5
    
    16 17 18 19 6
    15 24 25 20 7
    14 23 22 21 8
    13 12 11 10 9

    一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。

    Input

    输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

    Output

    输出最长区域的长度。

    Sample Input

    5 5
    1 2 3 4 5
    16 17 18 19 6
    15 24 25 20 7
    14 23 22 21 8
    13 12 11 10 9
    

    Sample Output

    25

    Source

     
    记忆化搜索,就是把搜到的值存起来,dp[i][j]代表的是到(i,j)这个点的最大步数。
    直接去深搜的话会超时
    这里说一说记忆化搜索的好处= =
    可以理解为:记忆化搜索=搜索的形式+动态规划的思想
    直接去搜索的话如果情况太多的话是会超时的
    直接DP的话,会产生很多重复的子结构,而且也会产生一些无效的子结构
    一起结合起来的话,搜索一个状态只遍历一次,可以剪枝,这样就可以节省空间的开销
    然后将搜索到的结果记录下来,遇到符合条件的结果直接返回就行了,没有必要再去搜索那个状态,因为之前已经搜索出结果了
    这是TLE代码:
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<stdlib.h>
     5 #include<algorithm>
     6 using namespace std;
     7 const int MAXN=100+5;
     8 const int INF=0x3f3f3f3f;
     9 int a[MAXN][MAXN];
    10 int vis[MAXN][MAXN];
    11 int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
    12 int n,m,ans,maxn;
    13 void DFS(int x,int y,int cur)
    14 {
    15     int xx,yy;
    16     if(cur>maxn)
    17         maxn=cur;
    18     if(a[x][y]<=a[x][y+1] && a[x][y]<=a[x+1][y] && a[x][y]<=a[x][y-1] && a[x][y]<=a[x-1][y])
    19         return ;
    20     for(int k=0;k<4;k++)
    21     {
    22         xx=x+dir[k][0];
    23         yy=y+dir[k][1];
    24         if(a[xx][yy]<a[x][y] && 0<=xx && xx<n && 0<=yy && yy<m)
    25         {
    26             vis[xx][yy]=1;
    27             DFS(xx,yy,cur+1);
    28             vis[xx][yy]=0;
    29         }
    30     }
    31 }
    32 int main()
    33 {
    34     //freopen("in.txt","r",stdin);
    35     while(scanf("%d %d",&n,&m)!=EOF)
    36     {
    37         for(int i=0;i<n;i++)
    38             for(int j=0;j<m;j++)
    39                 scanf("%d",&a[i][j]);
    40 
    41         for(int i=0;i<n;i++)
    42         {
    43             for(int j=0;j<m;j++)
    44             {
    45                 memset(vis,0,sizeof(vis));
    46                 DFS(i,j,1);
    47             }
    48         }
    49         cout<<maxn<<endl;
    50     }
    51     return 0;
    52 }
    View Code

    记忆化处理后AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<stdlib.h>
     5 #include<algorithm>
     6 using namespace std;
     7 const int MAXN=100+5;
     8 const int INF=0x3f3f3f3f;
     9 int a[MAXN][MAXN],vis[MAXN][MAXN],dp[MAXN][MAXN];
    10 int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
    11 int n,m,ans,maxn,len;
    12 int solve(int x,int y)
    13 {
    14     if(dp[x][y]!=0)
    15         return dp[x][y];
    16     maxn=0;
    17     for(int k=0;k<4;k++)
    18     {
    19         int xx=x+dir[k][0];
    20         int yy=y+dir[k][1];
    21         if(0<=xx&&xx<n && 0<=yy&&yy<m && a[x][y]>a[xx][yy])
    22         {
    23             len=solve(xx,yy);
    24             maxn=max(maxn,len);
    25         }
    26     }
    27     dp[x][y]=maxn+1;
    28     return maxn+1;
    29 }
    30 int main()
    31 {
    32     //freopen("in.txt","r",stdin);
    33     while(scanf("%d %d",&n,&m)!=EOF)
    34     {
    35         memset(dp,0,sizeof(dp));
    36         ans=-1;
    37         for(int i=0;i<n;i++)
    38             for(int j=0;j<m;j++)
    39                 scanf("%d",&a[i][j]);
    40 
    41         for(int i=0;i<n;i++)
    42         {
    43             for(int j=0;j<m;j++)
    44             {
    45                 dp[i][j]=solve(i,j);
    46                 if(dp[i][j]>ans)
    47                     ans=dp[i][j];
    48             }
    49         }
    50         cout<<ans<<endl;
    51     }
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    /etc/sysctl.conf 控制内核相关配置文件
    python 并发编程 非阻塞IO模型
    python 并发编程 多路复用IO模型
    python 并发编程 异步IO模型
    python 并发编程 阻塞IO模型
    python 并发编程 基于gevent模块 协程池 实现并发的套接字通信
    python 并发编程 基于gevent模块实现并发的套接字通信
    python 并发编程 io模型 目录
    python 并发编程 socket 服务端 客户端 阻塞io行为
    python 并发编程 IO模型介绍
  • 原文地址:https://www.cnblogs.com/clliff/p/3952387.html
Copyright © 2011-2022 走看看