[poj]1088-滑雪

滑雪

思路:

从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;
}
View Code

 

posted on 2015-03-07 11:28  cha1992  阅读(762)  评论(0编辑  收藏  举报

导航