1. 程式人生 > >滑雪 POJ - 1088 (基礎dp)

滑雪 POJ - 1088 (基礎dp)

這道題是一道比較基礎的dp問題, 最開始我用成Dfs來寫, 不出意外果然超時了

定義這道題的狀態dp[i][j]為  : 從i行j列出發的最大滑行長度

狀態轉移方程應該就是: dp[i][j] = max(dp[i][j], dp[i-1][j] | h[i][j] > h[i-1][j]), max(dp[i][j], dp[i+1][j] | h[i][j] > h[i+1][j]), 

                                                    max(dp[i][j], dp[i][j-1] | h[i][j] > h[i][j-1]),max(dp[i][j], dp[i][j+1] | h[i][j] > h[i][j+1])

然後牽扯到一個順序問題, 這道題目不能直觀的從前到後或從後到前, 需要對高度進行從小到大排序, 再依次遍歷

同時注意初始化問題和邊界問題, 各點初始化為1, 同時注意對越界情況的判斷

//滑雪
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef  long long LL;
const LL maxn = 110, maxh = 10010;

int R, C;
int dp[maxn][maxn]; //從i行j列出發的最大長度
int height[maxn][maxn]; //高度
struct Point{
    int x, y, h; //座標和高度;
}s[maxn*maxn];
bool cmp(Point a, Point b){
    return a.h < b.h; //按高度從小到大排序
}
int solve()
{
    for(int i = 0; i <= R+1; i++)
        for(int j = 0; j <= C+1; j++)
            dp[i][j] = 1;  //初始化為1
    sort(s+1, s+R*C+1, cmp);

    for(int i = 1; i <= R*C; i++){
        if(s[i].x+1<=R && height[s[i].x][s[i].y] > height[s[i].x+1][s[i].y])
            dp[s[i].x][s[i].y] = max(dp[s[i].x][s[i].y], dp[s[i].x+1][s[i].y]+1); //切記只有選了才+1
        if(s[i].x-1>0 && height[s[i].x][s[i].y] > height[s[i].x-1][s[i].y])
            dp[s[i].x][s[i].y] = max(dp[s[i].x][s[i].y], dp[s[i].x-1][s[i].y]+1);
        if(s[i].y+1<=C && height[s[i].x][s[i].y] > height[s[i].x][s[i].y+1])
            dp[s[i].x][s[i].y] = max(dp[s[i].x][s[i].y], dp[s[i].x][s[i].y+1]+1);
        if(s[i].y-1>0 && height[s[i].x][s[i].y] > height[s[i].x][s[i].y-1])
            dp[s[i].x][s[i].y] = max(dp[s[i].x][s[i].y], dp[s[i].x][s[i].y-1]+1);
    }
    int ans = 0;
    for(int i = 1; i <= R; i++)
        for(int j = 1; j <= C; j++)
            ans = max(ans, dp[i][j]);
    return ans;
}

int main()
{
    cin >> R >> C;
    int no = 1;
    for(int i = 1; i <= R; i++)
        for(int j = 1; j <= C; j++){
            cin >> height[i][j];
            s[no].x = i, s[no].y = j, s[no].h = height[i][j];
            no++;
        }
    cout << solve() << endl;
    return 0;
}