CodeForces 429B Working out (DP)
题意:从左上角到右下角 从左下角到右上角 两条路,求经历过的格子和最大,重叠的不算
分析:分别算出从四个角出发到任意一点的最大值,枚举交点即可。
#include <cstring> #include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <stack> #include <vector> #include <queue> using namespace std; int a[1006][1006]; int dp[5][1006][1006]; int main() { int n, m; 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]); } } for(int i=1; i<=4; i++) { dp[i][0][1] = 0, dp[i][1][0] = 0; dp[i][n][m+1] = 0, dp[i][n+1][m] = 0; dp[i][0][m] = 0, dp[i][1][m+1] = 0; dp[i][n+1][1] = 0, dp[i][n][0] = 0; } for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { dp[1][i][j] = max(dp[1][i][j-1], dp[1][i-1][j])+a[i][j]; } } for(int i=n; i>=1; i--) { for(int j=1; j<=m; j++) { dp[2][i][j] = max(dp[2][i][j-1], dp[2][i+1][j])+a[i][j]; } } for(int i=n; i>=1; i--) { for(int j=m; j>=1; j--) { dp[3][i][j] = max(dp[3][i][j+1], dp[3][i+1][j])+a[i][j]; } } for(int i=1; i<=n; i++) { for(int j=m; j>=1; j--) { dp[4][i][j] = max(dp[4][i][j+1], dp[4][i-1][j])+a[i][j]; } } int ans = 0; for(int i=2; i<n; i++) { for(int j=2; j<m; j++) { ans = max(ans, dp[1][i-1][j]+dp[3][i+1][j]+dp[2][i][j-1]+dp[4][i][j+1]); ans = max(ans, dp[1][i][j-1]+dp[3][i][j+1]+dp[2][i+1][j]+dp[4][i-1][j]); } } printf("%d\n", ans); } return 0; }