滑雪
思路:
从leetcode过来要自己写输入输出,很不习惯,leetcode果然只是针对面试的。
这个题目典型的动态规划,额外开辟一个二维数组f记录(i,j)点能够滑雪多少高度,最后f(i,j)中最大的值就是滑雪的最大高度。因为f(i,j)记录了相对高度,比如在求点(0,0)时,点(0,1)与点(1,0)都是未知的,这就需要递归,用回溯算法来求某个点的最大滑雪高度。
伪代码如下:
if f[i][j]已经计算过了
return f[i][j]
k=0->3循环(四个方向的循环)
(ni, nj) = (i, j)周围四个点
if ( (ni, nj)满足边界条件 && h[i][j]>h[ni][nj] && f[i][j]>f[ni][nj]+1 )
f[i][j] = f[ni][nj]+1
return f[i][j]
伪代码第5行中的判断有3个条件。第一个是边界条件,很显然。第二个是绝对高度,因为是向下滑,所以某点的绝对高度要比周围点的绝对高度要高才行。第三个是相对高度条件,f[ni][nj]要递归计算才行,也就是dp[ni][nj].
题解:
#include<iostream> #include<algorithm> #include <cstring> using namespace std; int dir[4][2] = {{-1,0},{0,-1},{1,0},{0,1}}; int r,c; //第一行的输入 int h[100][100], f[100][100]; bool validindex(int index, int b) { if(index>=0 && index<b) return true; return false; } int dp(int i, int j) { int k, ni, nj; if(f[i][j]>0) return f[i][j]; for(k=0;k<4;k++) { ni = i+dir[k][0]; nj = j+dir[k][1]; if(validindex(ni, r) && validindex(nj, c) && h[i][j]>h[ni][nj] && f[i][j]<1+dp(ni, nj)) f[i][j] = f[ni][nj]+1; } return f[i][j]; } int main() { int i,j,res; cin>>r>>c; for(i=0;i<r;i++) for(j=0;j<c;j++) cin>>h[i][j]; res = 0; memset(f, 0, sizeof(f)); for(i=0;i<r;i++) for(j=0;j<c;j++) f[i][j] = dp(i, j); for(i=0;i<r;i++) for(j=0;j<c;j++) if(f[i][j]>res) res = f[i][j]; cout<<res+1; return 0; }