http://acm.hust.edu.cn/vjudge/contest/126699#problem/E

 

题意:共有两个人,一个人A要求从(1, 1)走到(n,  n)(只能向右或向下),另一个人B要求从(n,  1)走到(1,  n)(只能向右或向上)。相遇时的格子的数值不算(只能相遇一个格子),问你两个人当都到达要求时的地点,最大数值为多少?

 

分析:先列举一个相遇时的格子,那么共有两种情况。(一种一个人从相遇点的左边过来,另一个人从相遇点的下面过来;另一种一个人从相遇点的上面过来,另一个人从相遇点的 右边过来)如图所示。

方法:求出每个相遇点到四个角的最大值,每个点分别在两种情形下四个dp相加的最大值即为所求

        

  

                     图  A                                                         图    B

 

 

 

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <math.h>

using namespace std;

#define oo 0x3f3f3f3f
const int maxn = 1100;

typedef long long LL;
int dp1[maxn][maxn], dp2[maxn][maxn], dp3[maxn][maxn], dp4[maxn][maxn], a[maxn][maxn];

int main()
{
    int n, m;

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

        memset(dp1, 0, sizeof(dp1));
        memset(dp2, 0, sizeof(dp2));
        memset(dp3, 0, sizeof(dp3));
        memset(dp4, 0, sizeof(dp4));

        ///左上
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                dp1[i][j] = max(dp1[i-1][j], dp1[i][j-1])+a[i][j];
            }
        }

        ///右上
        for(int i=1; i<=n; i++)
        {
            for(int j=m; j>=1; j--)
            {
                dp2[i][j] = max(dp2[i-1][j], dp2[i][j+1])+a[i][j];
            }
        }

        ///左下
        for(int i=n; i>=1; i--)
        {
            for(int j=1; j<=m; j++)
            {
                dp3[i][j] = max(dp3[i+1][j], dp3[i][j-1])+a[i][j];
            }
        }

        ///右下
        for(int i=n; i>=1; i--)
        {
            for(int j=m; j>=1; j--)
            {
                dp4[i][j] = max(dp4[i+1][j], dp4[i][j+1])+a[i][j];
            }
        }
        
        ///注意i,j的范围,因为两者的起点以及终点不能当做相遇的点
        int ans = 0;
        for(int i=2; i<n; i++)
        {
            for(int j=2; j<m; j++)
            {
                ans = max(ans, dp1[i][j-1]+dp2[i-1][j]+dp3[i+1][j]+dp4[i][j+1]);///对应图A
                ans = max(ans, dp1[i-1][j]+dp2[i][j+1]+dp3[i][j-1]+dp4[i+1][j]);///对应图B
            }
        }

        printf("%d\n", ans);
    }
    return 0;
}
View Code

 

posted on 2016-08-09 15:20  不忧尘世不忧心  阅读(420)  评论(0编辑  收藏  举报