滑雪 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;
}

猜你喜欢

转载自blog.csdn.net/a1097304791/article/details/83713364
今日推荐