动态规划解决北大 ACM 1088 滑雪问题

POJ1088

         以前一直想搞ACM,但一直没怎么动,没技术苦逼研究僧还是找不到工作,所以决心搞ACM,小伙伴们和我一起来学习吧。

         动态规划第一题 北大ACM 1088滑雪问题

问题描述:

滑雪

Time Limit: 1000MS

Memory Limit: 65536K

Total Submissions: 78013

Accepted: 28994

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

 

 

动态规划解题描述:

首先对所有元素排序,设为a1,a2,a3 ,a4,a5,a6….

然后按照升序顺序逐次求每个元素ax的最大长度,针对每个元素对上下左右四个方向的元素与元素ax的高度比较,如果比ax大,放弃,如果比ax小,则ax经过此元素形成长度加一的最长路径。

代码:

 

#include <iostream>

#include <cstdlib>

using namespace std;

 

/*

*记录高度值(用于排序)

*记录位置row col用于寻找周围元素

*/

struct element

{

    int data;

    int row;

    int col;

};

/*

*记录高度值和经过此点的最大长度

*/

struct arrnode

{

    int high;

    int mlen;

};

 

/*

*快排比较函数

*/

int compare( const void * ele1,const void * ele2)

{

    element *ele11 = (element *)ele1;

    element *ele22 = (element *)ele2;

    if ( ele11->data< ele22->data )

        return -1;

    else if( ele11->data ==ele22->data )

        return 0;

    else

        return 1;

}

 

/*

*分别从上下左右四个方向查看与row行col列元素x相邻的四个元素

*在四个元素中找高度值小于x并且长度最大的长度赋值给x的长度

*/

int Around_Max_length(int row, int col, arrnode * arr,int arrrow, int arrcol)

{

    int max = 1;

    int value = (*(arr+row*arrcol+col)).high;

    int tvalue = 0;

    int tlen = 0;

    if( (col – 1) >= 0 )

    {

        tvalue = (*(arr+row*arrcol+col-1)).high;

        tlen =  (*(arr+row*arrcol+col-1)).mlen;

        if( value > tvalue)

            max <(tlen+1) ? max=(tlen+1) : max = max;

    }

    if( (row – 1) >= 0 )

    {

        tvalue = (*(arr+(row-1)*arrcol+col)).high;

        tlen =  (*(arr+(row-1)*arrcol+col)).mlen;

        if( value > tvalue)

            max <(tlen+1) ? max=(tlen+1) : max = max;

    }

    if( (row + 1) < arrrow )

    {

        tvalue = (*(arr+(row+1)*arrcol+col)).high;

        tlen =  (*(arr+(row+1)*arrcol+col)).mlen;

        if( value > tvalue)

            max <(tlen+1) ? max=(tlen+1) : max = max;

    }

    if( (col + 1) < arrcol )

    {

        tvalue = (*(arr+row*arrcol+col+1)).high;

        tlen =  (*(arr+row*arrcol+col+1)).mlen;

        if( value > tvalue)

            max <(tlen+1) ? max=(tlen+1) : max = max;

    }

    return max;

}

int main()

{

    int r = 0 , c = 0 ;

    cin>>r>>c;

    arrnode * arr_high = new arrnode[r*c];

    element * listele = new element[r*c];

    int listnum = 0;

    //初始化

    for ( int i = 0; i < r;i++ )

    {

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

        {

            int t = 0;

            cin>>t;

            arrnode arn = {t,1};

            arr_high[listnum]= arn;

            element elet = {t,i,j};

            listele[listnum++]= elet;

        }

    }

    //快排

    qsort(listele,r*c,sizeof(element),compare );

    //对有序数组listele的每个元素依次计算其最大长度记录于arr_high用于以后计算的子问题的解

    for(int k = 0; k < r*c;k++ )

    {

        element fmlele =listele[k];

        int row = fmlele.row;

        int col = fmlele.col;

        arr_high[row*c+col].mlen= Around_Max_length(row,col,arr_high,r,c);

    }

 

    //遍历数组arr_high寻找最大长度

    int max = 0;

    for(int m = 0; m < r*c;m++ )

    {

        max <arr_high[m].mlen ? max = arr_high[m].mlen : max=max;

    }

    cout<<max<<endl;

 

    int kk;

    cin>>kk;

    return 0;

}

 

    原文作者:动态规划
    原文地址: https://blog.csdn.net/lxy54101/article/details/40687989
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞