赞
踩
本文讲述动态规划的经典问题——滑雪
采用递推的动态规划方式求解
先用结构体保存每个点对应的原本坐标位置和高度;
将所有点按高度从小到大排序;
用一个二维数组保存输入的原本数据,
再用一个二维数组保存对应位置的最大滑行距离;
从第二个点开始求解(因为第一个点高度最低,显然滑行距离为1)
依次和它在原本坐标里的上下左右四个方向进行判断,
如果它比某一方向上的高度高,则它的滑行距离就应该是相比较的最大滑行距离+1和它保存的最大滑行距离中的最大值
最后求完总共的点,进行遍历,得到最终最大值即可!
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
解题代码:
- #include<bits/stdc++.h>
- using namespace std;
- struct point{
- int r,c,h;
- }ps[10100];
- bool cmp(point a,point b){
- return a.h < b.h; //根据高度从小到大排序,依次求解
- }
- int f[110][110]; //保存输入的数组
- int ans[110][110]; //保存求值的结果
- int main(){
- int n,m; //行列 的数
- cin>>n>>m;
- //输入数组
- for(int i=0;i<n;i++)
- for(int j=0;j<m;j++){
- cin>>f[i][j];
- ps[i * m + j].h = f[i][j];
- ps[i * m + j].r = i;
- ps[i * m + j].c = j;
- ans[i][j] = 1; //初始化完成
- }
- sort(ps,ps+n*m,cmp);
- //开始求解
- for(int i = 1;i < n*m;i++){
- int r = ps[i].r;
- int c = ps[i].c; //得到行列的值
- //进行四个方向的判断
- if(r > 0 && ps[i].h > f[r-1][c]) //向上
- ans[r][c] = max(ans[r][c],ans[r-1][c]+1);
- if(c > 0 && ps[i].h > f[r][c-1]) //向左
- ans[r][c] = max(ans[r][c],ans[r][c-1]+1);
- if(r < n-1 && ps[i].h > f[r+1][c]) //向下
- ans[r][c] = max(ans[r][c],ans[r+1][c]+1);
- if(c < m-1 && ps[i].h> f[r][c+1]) //向右
- ans[r][c] = max(ans[r][c],ans[r][c+1]+1);
- }
- //输出结果
- int maxl = 0;
- for(int i=0;i<n;i++)
- for(int j=0;j<m;j++)
- maxl = max(maxl,ans[i][j]);
- cout<<maxl<<endl;
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。