Codeforces Round #245 (Div. 1) B. Working out (简单DP)

题目链接:http://codeforces.com/problemset/problem/429/B

给你一个矩阵,一个人从(1, 1) ->(n, m),只能向下或者向右; 一个人从(n, 1) ->(1, m),只能向上或者向右。必须有一个相遇点, 相遇点的值不能被取到, 问两个人能得到的最大路径和是多少?

dp[i][j]:表示从一个点出发的最大值;先预处理从(1,1) (1,m) (n,1) (n,m)四个点出发的4个dp最大值。然后枚举所有的点,但是这个点不能在边缘,考虑枚举点不够,还要考虑枚举这个点的上下左右的值。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN = 1e3 + 5;
 4 int dp1[MAXN][MAXN] , dp2[MAXN][MAXN] , dp3[MAXN][MAXN] , dp4[MAXN][MAXN];
 5 int a[MAXN][MAXN];
 6 
 7 int main()
 8 {
 9     int n , m;
10     scanf("%d %d" , &n , &m);
11     for(int i = 1 ; i <= n ; ++i) {
12         for(int j = 1 ; j <= m ; ++j) {
13             scanf("%d" , &a[i][j]);
14         }
15     }
16     for(int i = 1 ; i <= n ; ++i) {
17         for(int j = 1 ; j <= m ; ++j) {
18             dp1[i][j] = max(dp1[i - 1][j] , dp1[i][j - 1]) + a[i][j];
19         }
20     }
21     for(int i = n ; i >= 1 ; --i) {
22         for(int j = 1 ; j <= m ; ++j) {
23             dp2[i][j] = max(dp2[i + 1][j] , dp2[i][j - 1]) + a[i][j];
24         }
25     }
26     for(int i = 1 ; i <= n ; ++i) {
27         for(int j = m ; j >= 1 ; --j) {
28             dp3[i][j] = max(dp3[i][j + 1] , dp3[i - 1][j]) + a[i][j];
29         }
30     }
31     for(int i = n ; i >= 1 ; --i) {
32         for(int j = m ; j >= 1 ; --j) {
33             dp4[i][j] = max(dp4[i + 1][j] , dp4[i][j + 1]) + a[i][j];
34         }
35     }
36     int res = 0;
37     for(int i = 2 ; i < n ; ++i) {
38         for(int j = 2 ; j < m ; ++j) {
39             res = max(res , dp1[i][j - 1] + dp2[i + 1][j] + dp3[i - 1][j] + dp4[i][j + 1]);
40             res = max(res , dp1[i - 1][j] + dp2[i][j - 1] + dp3[i][j + 1] + dp4[i + 1][j]);
41         }
42     }
43     printf("%d\n" , res);
44     return 0;
45 }

 

posted @ 2016-06-04 22:41  Recoder  阅读(239)  评论(0编辑  收藏  举报