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 }