動態規劃(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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章