NYOJ 10 skiing动态规划心得

这道题目,拿到手中,首先想到的是搜索,但是,后来想了想搜索不知道从哪搜起,就看了一下分类,一看属于动态规划类的,因为以前没有接触过动态规划,所以在网上搜了一下动态规划的思想,看过之后也有想到将它们到周围其他的点的距离再保存到一个新的数组中, 但是,这样子写了一下,感觉不行,就在网上搜了一下,确实,方法比这个好多了, 只需要保存一个就行,也就是,之保存当前点能滑的最长距离,最后直接遍历数组,找到这个最大的距离就行了。这样一来,问题就简单多了,最后利用搜索跟动规结合,还是挺容易理解的。

/*************************************************************************
    > File Name:            3.cpp
    > Author:               Howe_Young
    > Mail:                 1013410795@qq.com
    > Created Time:         2015年08月16日 星期日 11时09分27秒
 ************************************************************************/

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
using namespace std;
typedef long long ll;
const int maxn = 1010;
int mat[maxn][maxn];
int d[maxn][maxn];
int n, m;
const int nx[4] = {1, -1, 0, 0}, ny[4] = {0, 0, 1, -1};
int dp(int i, int j)
{
    if (d[i][j] != 0)
        return d[i][j];
    d[i][j] = 1;
    for (int k = 0; k < 4; k++)
    {
        int x = nx[k] + i;
        int y = ny[k] + j;
        if (x >= 1 && x <= n && y >= 1 && y <= m && mat[i][j] > mat[x][y])
                d[i][j] = max(d[i][j], dp(x, y) + 1);
    }
    return d[i][j];
}
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        char name[1000];
        scanf("%s %d %d", name, &n, &m);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                scanf("%d", &mat[i][j]);
        memset(d, 0, sizeof(d));
        int ans = 0;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                ans = max(ans, dp(i, j));
        printf("%s: %d\n", name, ans);
        //cout << name << ": " << ans << endl;
    }
    return 0;
}
View Code

 

下面的这个是最优代码,但是我看到有些地方可以改进,这样可以使程序更快,我就稍微改进了一点点,主要就是增加了临时变量来保存那个递归调用的结果,还有就是初始化的时候,用的memset, 这样如果数据量大的话会很快。

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 int r, c;
 5 int Map[110][110], MaxLen[110][110];//Map用来存放地图,MaxLen用来存放当前点的能滑最大距离
 6 int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
 7 int search_MaxLen(int x, int y)
 8 {
 9     int len = 0;
10     if(x < 1 || y < 1 || x > r || y > c)//判断越界
11         return 0;
12     if(MaxLen[x][y] != 0)//如果已经找到,返回
13         return MaxLen[x][y];
14     for(int i = 0; i < 4; i++)
15     {
16         if(Map[x][y] > Map[x + dir[i][0]][y + dir[i][1]])
17         {
18             len = search_MaxLen(x + dir[i][0], y + dir[i][1]);
19             if(len > MaxLen[x][y])
20                 MaxLen[x][y] = len;
21         }
22     }
23     return ++MaxLen[x][y];
24 }
25 int main()
26 {
27     int t;
28     scanf("%d", &t);
29     while(t--)
30     {
31         int len = 0, max_len = 0;
32         memset(MaxLen, 0, sizeof(MaxLen));
33         scanf("%d %d", &r, &c);
34         for(int i = 1; i <= r; i++)
35             for(int j = 1; j <= c; j++)
36                 scanf("%d", &Map[i][j]);
37         for(int i = 1; i <= r; i++)
38         {
39             for(int j = 1; j <= c; j++)
40             {
41                 len = search_MaxLen(i, j);
42                 if(len > max_len)
43                     max_len = len;
44             }
45         }
46         printf("%d\n", max_len);
47     }
48     return 0;
49 }

 

posted @ 2014-09-29 16:50  Howe_Young  阅读(283)  评论(0编辑  收藏  举报