您的位置:首页 > 其它

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

2014-11-01 23:04 246 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: