POJ 1088 滑雪

给出一个R×C的地图,以及每个点的海拔,问下降序列最长多大?

简单的DP,记忆化搜索;

dp(i, j)

if f[i, j]已经计算过

  return f[i, j];

f[i, j] = 1;

for i = 1:k

  (ni, nj) = (i, j) + d[k];

  if  (ni, nj)合法 && h[i, j] > h[ni, nj]

    then f[i, j] = dp[ni, nj] + 1;

return f[i, j];

/* 滑雪:简单dp */

# include <stdio.h>
# include <string.h>

# define IN(x,low,high) ((x)>=(low) && (x)<=(high))

# define MAXN 101

const short int d[4][2] = {{-1,0}, {0, 1}, {1, 0}, {0, -1}};
short int R, C;
short int h[MAXN][MAXN], f[MAXN][MAXN];

int dp(int i, int j)
{
    int k, ni, nj;
    
    if (f[i][j] > 0) return f[i][j];
    f[i][j] = 1;
    for (k = 0; k < 4; ++k)
    {
        ni = i + d[k][0];
        nj = j + d[k][1];
        if (IN(ni, 1, R) && IN(nj, 1, C) && h[i][j] > h[ni][nj] && f[i][j] < dp(ni, nj)+1)
            f[i][j] = f[ni][nj] + 1;
    }
    
    return f[i][j];
}

int main()
{
    int i, j, ans;
    
    while (~scanf("%d%d", &R, &C))
    {
        for (i = 1; i <= R; ++i)
        for (j = 1; j <= C; ++j)
            scanf("%d", &h[i][j]);
        
        ans = 0;        
        memset(f, -1, sizeof(f));
        for (i = 1; i <= R; ++i)
        for (j = 1; j <= C; ++j)
            if (ans < dp(i,j)) ans = f[i][j];
        
        printf("%d\n", ans);
    }
    
    return 0;
}

posted on 2012-04-16 23:29  getgoing  阅读(1165)  评论(0编辑  收藏  举报

导航