zoukankan      html  css  js  c++  java
  • POJ1088滑雪记忆化搜索

    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

    题意:在给定区域内找出一列递减的序列,输出长度即可。

    思路:这一题之前写过两遍,是利用dfs进行搜索记录长度。

    注意:记忆化搜索的本质是遇到已经计算过的点直接返回该值即可,不需要进行标记。但是为啥返回的时候步数不用-1我也不知道。。

    先上之前dfs过的代码:

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<string.h>
     4 using namespace std;
     5 
     6 int aa,bb;
     7 int a[110][110];
     8 int ss[110][110];
     9 
    10 int dir[4][2]= {{1,0},{-1,0},{0,-1},{0,1}};
    11 int dfs(int x,int y)
    12 {
    13     if(ss[x][y]!=0)
    14         return ss[x][y];
    15     for(int i=0; i<4; i++)
    16     {
    17         int tx=x+dir[i][0];
    18         int ty=y+dir[i][1];
    19         if(tx>=0&&tx<aa&&ty>=0&&ty<bb&&a[tx][ty]<a[x][y])
    20         {
    21             int maxx=dfs(tx,ty)+1;
    22             if(maxx>ss[x][y])
    23             {
    24                 ss[x][y]=maxx;
    25             }
    26         }
    27     }
    28     return ss[x][y];
    29 }
    30 int main()
    31 {
    32     cin>>aa>>bb;
    33     memset(a,0,sizeof(a));
    34     memset(ss,0,sizeof(ss));
    35     for(int i=0; i<aa; i++)
    36     {
    37         for(int j=0; j<bb; j++)
    38         {
    39             cin>>a[i][j];
    40         }
    41     }
    42 
    43     int ans=-1;
    44     for(int i=0; i<aa; i++)
    45     {
    46         for(int j=0; j<bb; j++)
    47         {
    48           ss[i][j]=dfs(i,j);
    49             ans=max(ss[i][j],ans);
    50         }
    51     }
    52     cout<<ans+1<<endl;
    53     return 0;
    54 }
    View Code

    另外一种写法:

    由于今天做题目碰到一题需要记录路径的,发现用dfs写再通过回溯好像是没法实现,所以换了一种写法写这道题,但是思路还是和dfs的差不多。

    这一题记录好坐标后需要进行排序,一定要排序,不懂得话可以用

    2  3

    6  5  4 

    3  2  1这组例子来测试一下结果

    必须要排序,从大到小或者从小到的都可以,控制好后面代码的比较就可以了
    我的代码是从小到大排序,所以在后面实现的时候找的从当前该点出发,找四周小于该点的
    因为从小到大比较,所以每个点的状态都来自于前一个比它小的点,所以从小到大排序,从大的往小的上面找,有点dp的感觉

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<string.h>
     5 using namespace std;
     6 const int N=110;
     7 //h减小
     8 int dp[N][N];
     9 int a[N][N];
    10 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    11 
    12 
    13 struct node
    14 {
    15     int x;
    16     int y;
    17     int z;
    18 }e[N*N];
    19 
    20 int cmp1(node xx,node yy)
    21 {
    22     return xx.z<yy.z;
    23 }
    24 int main()
    25 {
    26     int m,n;
    27         scanf("%d %d",&m,&n);
    28     int p=0;
    29     for(int i=1;i<=m;i++)
    30     {
    31         for(int j=1;j<=n;j++)
    32         {
    33             scanf("%d",&a[i][j]);//需要存一下,否则后面没法比较
    34          //   scanf("%d",&kk);
    35             e[p].x=i;
    36             e[p].y=j;
    37             e[p++].z=a[i][j];
    38             dp[i][j]=1;
    39         }
    40     }
    41     sort(e,e+p,cmp1);//必须要排序,从大到小或者从小到的都可以,控制好后面代码的比较就可以了
    42     //我的代码是从小到大排序,所以在后面实现的时候找的从当前该点出发,找四周小于该点的
    43     //因为从小到大比较,所以每个点的状态都来自于前一个比它小的点,所以从小到大排序,从大的往小的上面找,有点dp的感觉
    44     int pp,qq,ww;
    45     int maxx=-1;
    46     for(int i=0;i<p;i++)
    47     {
    48         //    cout<<e[i].x<<" "<<e[i].y<<" "<<e[i].z<<endl;
    49         pp=e[i].x;
    50         qq=e[i].y;
    51         ww=e[i].z;
    52         for(int j=0;j<4;j++)
    53         {
    54             int tx=pp+dir[j][0];
    55             int ty=qq+dir[j][1];
    56             if(tx>=1&&tx<=m&&ty>=1&&ty<=n&&a[tx][ty]<ww)
    57             {
    58                 dp[pp][qq]=max(dp[pp][qq],dp[tx][ty]+1);
    59             }
    60         }
    61         maxx=max(maxx,dp[pp][qq]);
    62     }
    63     printf("%d\n",maxx);
    64     return 0;
    65 }
  • 相关阅读:
    coco2d-js demo程序之滚动的小球
    【leetcode】Happy Number(easy)
    【leetcode】Remove Linked List Elements(easy)
    【leetcode】LRU Cache(hard)★
    【QT】计时器制作
    【leetcode】Min Stack(easy)
    【leetcode】Compare Version Numbers(middle)
    【leetcode】Excel Sheet Column Title & Excel Sheet Column Number (easy)
    【leetcode】Binary Search Tree Iterator(middle)
    【leetcode】Number of Islands(middle)
  • 原文地址:https://www.cnblogs.com/OFSHK/p/11397122.html
Copyright © 2011-2022 走看看