滑雪

来源:互联网 发布:mac系统还原 编辑:程序博客网 时间:2024/04/29 04:08

滑雪

问题描述

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

1 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 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 51 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9

输出样例

25

定义状态co[i][j]为到坐标为(i,j)的点的最长路径
可以用动态规划的思路解决。在读入时按照点的高度排序,在接下来从低到高(从高到底亦可),有以下关系:
对于一个点而言,其路径长度无非是从四周比其低的点转移来的,不然则说明自己即为周遭最低的点。因此co[i][j] = max(co[i - 1][j], co[i + 1][j], co[i][j - 1], co[i][j + 1], 1)

另一种解法将这个问题视为“最长路”问题, 人为设定一个虚拟节点, 距离为0, 能走到任何节点,接下来即可用单源点最长路解决问题。
虚拟终点的设定也适用于最短路问题。

以下为动态规划代码。

//ski#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <vector>using namespace std;struct point{    int r;    int c;    point(int _r, int _c){        r = _r;        c = _c;    }};//var & constconst int maxN = 101;int r, c;int height[maxN][maxN];int co[maxN][maxN];vector<point> p[10010];int maks = 0;int finalM = 0;//funcvoid init();void readin();int findSmallest();void print();void calcCount();bool checkbound(int _c, int _r);bool islower(int c, int r, int c1, int r1);int main(){    init();    readin();    calcCount();    print();    return 0;}void init(){    freopen("ski.in", "r", stdin);    freopen("ski.out", "w", stdout);    r = c = 0;    memset(height, -1, sizeof(height));    memset(co, -1, sizeof(co));}void readin(){    cin >> r >> c;    for (int i = 1; i <= r; i++){        for (int j = 1; j <= c; j++){            cin >> height[i][j];            p[height[i][j]].push_back(point(i, j));            if (height[i][j] > maks) maks = height[i][j];        }    }}int findSmallest(){    for (int i = 0; i <= maks; i++){        if (!p[i].empty()){            return i;        }    }    return -1;}bool checkbound(int _c, int _r){    return (0 <= _c && _c <= c) && (0 <= _r && _r <= r);}bool islower(int c, int r, int c1, int r1){    return (height[r][c] < height[r1][c1]);}void calcCount(){    int s = findSmallest();    for (int i = 0; i < p[s].size(); i++){        co[p[s][i].r][p[s][i].c] = 1;    }    for (int i = s; i <= maks; i++){        for (int j = 0;j < p[i].size(); j++){            int c = p[i][j].c;            int r = p[i][j].r;            co[r][c] = 1;            if (checkbound(c - 1, r) && islower(c - 1, r, c, r)) co[r][c] = max(co[r][c], co[r][c - 1] + 1);            if (checkbound(c + 1, r) && islower(c + 1, r, c, r)) co[r][c] = max(co[r][c], co[r][c + 1] + 1);            if (checkbound(c, r + 1) && islower(c, r + 1, c, r)) co[r][c] = max(co[r][c], co[r + 1][c] + 1);            if (checkbound(c, r - 1) && islower(c, r - 1, c, r)) co[r][c] = max(co[r][c], co[r - 1][c] + 1);            if (co[r][c] > finalM) finalM = co[r][c];        }    }}void print(){    cout << finalM << endl;}
原创粉丝点击