zoukankan      html  css  js  c++  java
  • Poj_1088_滑雪(DP)

    一、Description(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

    输出最长区域的长度。

    二、问题分析

          典型的DP问题,动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。

          解这个问题与解其它的DP问题几乎没有什么两样。第一步找到问题的“状态”,第二步找到“状态转移方程”,然后基本上问题就解决了。首先,我们要找到这个问题中的“状态”是什么?我们必须注意到的一点是,到达一个坐标的方式最多有四种:上下左右四个方向,而且值必须必坐标值要大。然后再从这四个来源中选取符合要求的点,并从中选出S[i][j]最大的,也就是路径长度最长的,而所选出的这个坐标又可以当成是一个子问题递归求解。由于使用了记忆化存储,所以可以先直接查表,如果表中存在子问题的解则直接返回,否则就按上面的分析过程找到最大路径并存储。经过上面的分析,很容易可以得出问题的状态和状态转移方程。

    S[i][j]=1 + max(S[i-1][j], if i>0 ; S[i][j-1], if j>0;S[i+1][j] , if i<m-1 ; S[i][j+1], if  j<n-1 )

    三、解决方案

           有了上面的分析,编码就比较简单了。用一个二维数组用于读取坐标,再用一个二维数组用于记忆化存储。再写一个方法计算每一个坐标的值,并从四个方向分析上一步的最大值,并递归调用方法。算出本坐标的最大值并存储。最后,找出S数组中的最大值即是所求的最大路径。

    import java.util.Scanner;
    public class N1088_skate{
      private int h[][]=new int[101][101];
      private int m[][]=new int[101][101];
      private int r,c;
    
      private void init(){
        Scanner sc=new Scanner(System.in);
        r=sc.nextInt();
        c=sc.nextInt();     
        for(int i=0;i<r;i++)
            for(int j=0;j<c;j++){
                h[i][j]=sc.nextInt();
        		m[i][j]=-1;
            }
      }
    
      //递归获取从点(i,j)出发滑行的最大长度
      public int searchWithMenmo(int x,int y){
    		if( m[x][y]!=-1)
    		    return m[x][y];
    		else{
    			int max=0;
    			if(x>=1){
    				if(h[x-1][y]>h[x][y]){
    					max=Math.max(max,searchWithMenmo(x-1,y));
    				}
    			}
    			if(y>=1){
    				if(h[x][y-1]>h[x][y]){
    					max=Math.max(max,searchWithMenmo(x,y-1));
    				}
    			}
    			if(x<r-1){
    				if(h[x+1][y]>h[x][y]){
    					max=Math.max(max,searchWithMenmo(x+1,y));
    				}
    			}
    			if(y<c-1){
    				if(h[x][y+1]>h[x][y]){
    					max=Math.max(max,searchWithMenmo(x,y+1));
    				}
    			}
    			m[x][y]=max+1;
    			return m[x][y];
    	}
      }
    
     public int getMaxHeight(){
       int temp;
       int Max=-1;
       for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                temp=searchWithMenmo(i,j);
                if(Max< temp)
                    Max=temp;    
            }
        }
        return Max;
      }
      public static void main(String args[]){
        N1088_skate m=new N1088_skate();
        m.init();
        System.out.println(m.getMaxHeight());
      	}
    }


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    再谈TextField
    IOS-TextField知多少
    leftBarButtonItems
    LeftBarButtonItems,定制导航栏返回按钮
    Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法 Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法
    Unrecognized Selector Sent to Instance问题之诱敌深入关门打狗解决办法
    UNRECOGNIZED SELECTOR SENT TO INSTANCE 问题快速定位的方法
    Present ViewController,模态详解
    UILABEL AUTOLAYOUT自动换行 版本区别
    iOS自动布局解决警告Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
  • 原文地址:https://www.cnblogs.com/AndyDai/p/4734219.html
Copyright © 2011-2022 走看看