Code[VS] 2152 滑雪题解
2016-09-14 15:46
411 查看
[b]Code[VS] 2152 滑雪题解[/b]
题目描述 Descriptiontrs喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。
输入描述 Input Description
输入文件
第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
第2..r+1行:每行c个数,表示这个矩阵。
输出描述 Output Description
输出文件
仅一行: 输出1个整数,表示可以滑行的最大长度。
样例输入 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
数据范围及提示 Data Size & Hint
1s
————————————————————————————分割线————————————————————————————
初见此题时,便想到记忆化DFS的方法,由于本题数据较小,可以轻松过。但是,当数据再大一点,再用递归便不太合适。那么,如何用非递归方法解决这个问题?
仔细观察问题,发现最长上升子序列问题与本题有几分相像,如何将二维问题转为一维问题是解题的关键。
我们将每个山依照高度排序放置到一个一维数组中,并记录下原始的坐标,这时再进行最长上升子序列,只需要在其中,加入两个山是否相邻的判断即可 。
此方法可以避免,数据规模较大时,由于递归层数过深导致的堆栈溢出。同时也十分容易理解。
代码如下:
//Code By DrSHHHS #include "bits/stdc++.h" using namespace std ; const int maxN = 10010 ; const int INF = 2147483647 ; struct Slide {int x , y , val ;}; Slide arr[maxN] ; int f[maxN] ; bool cmp ( Slide a , Slide b ) { return a.val > b.val ;} int Abs ( int x ) { return x>0?x:-x ;} int Max ( int a , int b ){ return a>b?a:b ; } bool Judge ( int p1 , int p2 ) {//判断两座山是否相邻且严格下降 if (( Abs ( arr[p1].x - arr[p2].x) + Abs ( arr[p1].y - arr[p2].y) )==1 && arr[p2].val > arr[p1].val) return true ; else return false ; } int main ( ) { int N , M , tmp , K = 0 ,ans = -INF ; scanf("%d%d",&N ,&M ) ; for ( int i=1 ; i<=N ; ++i ){ for ( int j=1 ; j<=M ; ++j ){ K++; scanf( "%d" , &tmp ) ;//将二维数组读入一个一维数组arr中 arr[K].val = tmp ; arr[K].x = i ;arr[K].y = j ;//记录原始坐标 } } sort ( arr+1 , arr+K+1 , cmp ) ;//排序 f[1] = 1 ; for ( int i=2 ; i<=K ; ++i ){//最长下降子序列 for ( int j=1 ; j<=i-1 ; ++j ) { if ( Judge ( i , j ) ){//判断相邻切严格下降 f[i] = Max ( f[i] , f[j] ) ; } } f[i] = f[i] + 1 ; } for ( int i=1 ; i<=K ; ++i ){//找最大值 ans = Max ( f[i] , ans ) ; } printf ( "%d" , ans ) ; return 0 ; }
PS : 这个问题可视为最长下降子序列在二维中的拓展。
顺便附上记忆化搜索的代码,如下:
#include "bits/stdc++.h" using namespace std ; const int maxN = 110 ; int h[maxN][maxN] , f[maxN][maxN] ; int n, m, ans = 1; int DFS(int x, int y) { if( f[x][y] )return f[x][y]; f[x][y] = 1; if(x > 1 && h[x][y] < h[x - 1][y])f[x][y] = max(f[x][y], DFS(x - 1, y) + 1); if(y > 1 && h[x][y] < h[x][y - 1])f[x][y] = max(f[x][y], DFS(x, y - 1) + 1); if(x < n && h[x][y] < h[x + 1][y])f[x][y] = max(f[x][y], DFS(x + 1, y) + 1); if(y < m && h[x][y] < h[x][y + 1])f[x][y] = max(f[x][y], DFS(x, y + 1) + 1); ans = max(ans, f[x][y]); return f[x][y]; } int main() { scanf("%d%d", &n, &m); for ( int i = 1 ; i <= n ; i++ ) for ( int j = 1 ; j <= m ; j++ ) scanf( "%d" , &h[i][j] ) ; for(int i = 1 ; i <= n ; i++ ) for(int j = 1 ; j <= m ; j++ ) f[i][j] = DFS( i , j ) ; printf("%d", ans); return 0; }
2016-09-14 15:45:58
[b](完)[/b]
相关文章推荐
- 南阳oj 28 大数阶乘
- iOS集成IJKPlayer
- ios 设计模式汇总
- hdu5536Chip Factory+字典树
- Plan early!
- cesium三维地图效果
- poj 1321
- AlertDialog的几种用法
- 使用Alluxio优化Spark RDD
- Stanford CoreNLP 3.6.0 使用入门
- mapreduce-实现多表关联
- OS 学习笔记导航
- 网站备份脚本
- Oracle学习笔记之第八节sql语句(开发课学生指南051)
- Configuring the Avatar
- centos7 yum安装 mysql 5.6
- 数据库安全 Oracle审计Audit
- LeetCOde------3.Longest Substring Without Repeating Characters
- Android 雷达扫描效果、动画SweepGradient
- opencv安装教程