动态规划(1) 编程题#2: 滑雪(C++ STL中Map的按Key排序和按Value排序,memset函数直接将数组中的元素全部置成某个数,常函数)

编程题#2: 滑雪

来源: POJ (http://bailian.openjudge.cn/practice/1088/)

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
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

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-…-3-2-1更长。事实上,这是最长的一条。

输入
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

输出
输出最长区域的长度。

样例输入

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

样例输出

25

思路:
L(i,j)表示从点(i,j)出发的最长滑行长度。
一个点(i,j), 如果周围没有比它低的点, L(i,j) = 1
每个点的 L 值都初始化为1
将所有点按高度从小到大排序,从小到大遍历所有的点,用 multimap 容器实现
经过一个点(i,j)时,用递推公式求L(i,j)

程序解答:

#include <iostream>
//#include <memory>
#include <map>
#include <algorithm>
using namespace std;

struct coordinate{   //高度的坐标类
    int x, y;
};

//C++ STL中Map的按Key排序和按Value排序 https://www.cnblogs.com/lakeone/p/5599047.html
//自定义map容器中的比较大小顺序,按Key排序
struct MyCompare{   
    bool operator()(const int& a, const int& b){    //这里或者写成 bool operator()(int a, int b) const{ http://zh.cppreference.com/w/cpp/algorithm/sort
        return a < b;
    }
};

int main() {
    int R, C;
    int L[102][102];  //滑行长度
    int H[102][102];  //高度
    //memset(L, 1, sizeof(L));   //memset函数直接将数组中的元素全部置成 1  http://zh.cppreference.com/w/cpp/string/byte/memset
    //memset(H, 10000, sizeof(H));   //所有位置的高度全部置为 10000,此处不行! http://blog.csdn.net/my_business/article/details/40537653
    for (int i = 0; i < 102; i++){
        for (int j = 0; j < 102; j++){
            L[i][j] = 1;
            H[i][j] = 10000;
            //cout << L[i][j] << " " << H[i][j] << "   ";
        }
        //cout << endl;
    }
    int maxL = 0;
    coordinate position;
    multimap<int, coordinate, MyCompare> height;   //这里要用multimap容器,因为可能出现相同高度的位置点!
    multimap<int, coordinate, MyCompare>::iterator hi;

    cin >> R >> C;
    for (int i = 1; i <= R; i++){
        for (int j = 1; j <= C; j++){
            cin >> H[i][j];
            position.x = i;
            position.y = j;
            height.insert({ H[i][j], position });   //把每个位置的高度和坐标放入map容器中
        }
    }

    int Lx, Ly; //位置的坐标
    for (hi = height.begin(); hi != height.end(); hi++){
        //cout << hi->first << " " << hi->second.x << " " << hi->second.y << " " << H[hi->second.x][hi->second.y] << endl;
        Lx = hi->second.x;
        Ly = hi->second.y;
        if (H[Lx][Ly] <= H[Lx - 1][Ly] && H[Lx][Ly] <= H[Lx + 1][Ly] && H[Lx][Ly] <= H[Lx][Ly - 1] && H[Lx][Ly] <= H[Lx][Ly + 1]){
            L[Lx][Ly] = 1;
        }
        else{
            if (H[Lx][Ly] > H[Lx - 1][Ly])
                L[Lx][Ly] = max(L[Lx][Ly], L[Lx - 1][Ly] + 1);
            if (H[Lx][Ly] > H[Lx + 1][Ly])
                L[Lx][Ly] = max(L[Lx][Ly], L[Lx + 1][Ly] + 1);
            if (H[Lx][Ly] > H[Lx][Ly - 1])
                L[Lx][Ly] = max(L[Lx][Ly], L[Lx][Ly - 1] + 1);
            if (H[Lx][Ly] > H[Lx][Ly + 1])
                L[Lx][Ly] = max(L[Lx][Ly], L[Lx][Ly + 1] + 1);
        }
        if (maxL < L[Lx][Ly])
            maxL = L[Lx][Ly];
    }

    cout << maxL << endl;

    return 0;
}

其它解法参考:
https://www.cnblogs.com/Konayuki2015/p/4514285.html
http://www.cnblogs.com/dagon/p/4849857.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值