POJ 1088 滑雪 (DPor记忆化搜索)

题目大意:中文题:http://poj.org/problem?id=1088

先上一发自己写的记忆化,渣,900多毫秒

#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>

using namespace std;

int a[111][111];
int visit[111][111];
int dp[111][111];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int ans = 0;

void DFS(int x, int y, int s)
{
    if(dp[x][y]>=s)
        return ;
    visit[x][y]++;
    dp[x][y] = s;
    ans = max(ans, s);
    for(int i=0; i<4; i++)
    {
        int xx = x+dir[i][0];
        int yy = y+dir[i][1];
        if(visit[xx][yy] && a[xx][yy]>a[x][y])
        {
            DFS(xx, yy, s+1);
        }

    }
}

int main()
{
    int n, m;
    memset(visit, 0, sizeof(visit));
    while(~scanf("%d %d", &n, &m))
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                scanf("%d", &a[i][j]);
                visit[i][j] = 1;
            }
        }
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                if(visit[i][j]==1)
                DFS(i, j, 1);
        printf("%d
", ans);
    }

    return 0;
}
/*
3 5
1 2 3 4 4
1 1 1 5 1
2 3 4 5 6
*/
渣渣

再看看他人的好的记忆化

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>

using namespace std;

#define N 110
#define met(a, b) memset(a, b, sizeof(a))

typedef long long LL;

int n, m, dp[N][N], A[N][N], ans;
int dir[4][2] = { {-1, 0},{1, 0},{0, -1},{0, 1} };

int dfs(int x, int y)
{
    if(dp[x][y]) return dp[x][y];
    int Max = 0;
    for(int i=0; i<4; i++)
    {
        int px = x+dir[i][0];
        int py = y+dir[i][1];
        if(px>0 && py>0 && px<=m && py<=n && A[px][py]<A[x][y])
            Max = max(Max, dfs(px, py));
    }
    dp[x][y] = Max+1;
    ans = max(ans, dp[x][y]);
    return dp[x][y];
}

int main()
{
    while(scanf("%d %d", &m, &n)!=EOF)
    {
        met(A, 0);
        for(int i=1; i<=m; i++)
        {
            for(int j=1; j<=n; j++)
                scanf("%d", &A[i][j]);
        }
        met(dp, 0);

        ans = 0;

        for(int i=1; i<=m; i++)
        {
            for(int j=1; j<=n; j++)
            {
                dfs(i, j);
            }
        }
        printf("%d
", ans);
    }
    return 0;
}
厉害

再看看用DP式写的

先进行点的排序

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>

using namespace std;

#define N 110
#define met(a, b) memset(a, b, sizeof(a))

typedef long long LL;

int n, m, dp[N][N], A[N][N];
int dir[4][2] = { {-1, 0},{1, 0},{0, -1},{0, 1} };

struct node
{
    int x, y, w;
    friend bool operator<(node p, node q)
    {
        return p.w < q.w;
    }
}a[N*N];

int main()
{
    while(scanf("%d %d", &m, &n)!=EOF)
    {
        met(a, 0);
        met(A, 0);
        int len = 0;
        for(int i=1; i<=m; i++)
        {
            for(int j=1; j<=n; j++)
            {
                scanf("%d", &A[i][j]);
                a[len].x = i;
                a[len].y = j;
                a[len++].w = A[i][j];
            }
        }
        sort(a, a+len);
        met(dp, 0);
        int ans = 0;
        for(int i=0; i<len; i++)
        {
            int Max = 0;
            for(int j=0; j<4; j++)
            {
                int p = a[i].x + dir[j][0];
                int q = a[i].y + dir[j][1];
                if(A[p][q] < a[i].w )
                    Max = max(Max, dp[p][q]);
            }
            dp[a[i].x][a[i].y] = Max + 1;
            ans = max(ans, Max+1);
        }
        printf("%d
", ans);
    }
    return 0;
}
/*
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
*/
膜拜
原文地址:https://www.cnblogs.com/mengzhong/p/5728309.html