Description
Summer is coming! It‘s time for Iahub and Iahubina to work out, as they both want to look hot at the beach. The gym where they go is a matrix a with n lines and m columns. Let number a[i][j] represents the calories burned by performing workout at the cell of gym in thei-th line and the j-th column.
Iahub starts with workout located at line 1 and column 1. He needs to finish with workout a[n][m]. After finishing workout a[i][j], he can go to workout a[i + 1][j] or a[i][j + 1]. Similarly, Iahubina starts with workout a[n][1] and she needs to finish with workouta[1][m]. After finishing workout from cell a[i][j], she goes to either a[i][j + 1] or a[i - 1][j].
There is one additional condition for their training. They have to meet in exactly one cell of gym. At that cell, none of them will work out. They will talk about fast exponentiation (pretty odd small talk) and then both of them will move to the next workout.
If a workout was done by either Iahub or Iahubina, it counts as total gain. Please plan a workout for Iahub and Iahubina such as total gain to be as big as possible. Note, that Iahub and Iahubina can perform workouts with different speed, so the number of cells that they use to reach meet cell may differs.
Input
The first line of the input contains two integers n and m (3 ≤ n, m ≤ 1000). Each of the next n lines contains m integers: j-th number from i-th line denotes element a[i][j] (0 ≤ a[i][j] ≤ 105).
Output
The output contains a single number — the maximum total gain possible.
题目大意:两个人(假设为A,B),打算健身,有N行M列个房间,每个房间能消耗Map[i][j]的卡路里,A起点为(1,1)要达到(n,m)点,且每次只能向右走一步或向下走一步,B起点为(n,1),要达到(1,m),且每次只能向上走一步,或向右走一步。有要求A,B必须在某一个房间相遇一次,且A,B在该房间不再消耗卡路里,因为两人锻炼身体的速度不同,所以在相遇时经过的房间数亦可能不相同。问两人合计最多消耗多少卡路里。
题目思路:分别从四个角向对角打dp表,然后遍历各个点认为该点为相遇的房间,依据该点求四个dp式的和,并找出最大值,具体看代码。
#include<cstdio> #include<stdio.h> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<string> #include<cstring> #include<vector> #include<queue> #define INF 0x3f3f3f3f #define MAX 1005 using namespace std; long long dp1[MAX][MAX],dp2[MAX][MAX],dp3[MAX][MAX],dp4[MAX][MAX],ans; int Map[MAX][MAX],n,m; void Ans() { memset(dp1,0,sizeof(dp1)); memset(dp2,0,sizeof(dp2)); memset(dp3,0,sizeof(dp3)); memset(dp4,0,sizeof(dp4)); int i,j; for(i=1; i<=n; i++)//dp1 { for(j=1; j<=m; j++) { dp1[i][j]=Map[i][j]+max(dp1[i-1][j],dp1[i][j-1]); } } for(i=n; i>=1; i--)//dp2 { for(j=m; j>=1; j--) { dp2[i][j]=Map[i][j]+max(dp2[i+1][j],dp2[i][j+1]); } } for(i=1; i<=n; i++)//dp3 { for(j=m; j>=1; j--) { dp3[i][j]=Map[i][j]+max(dp3[i-1][j],dp3[i][j+1]); } } for(i=n; i>=1; i--)//dp4 { for(j=1; j<=m; j++) { dp4[i][j]=Map[i][j]+max(dp4[i+1][j],dp4[i][j-1]); } } } int main() { int i,j; while(scanf("%d%d",&n,&m)!=EOF) { ans=0; for(i=1; i<=n; i++) for(j=1; j<=m; j++) scanf("%d",&Map[i][j]); Ans(); for(i=2; i<n; i++)//因为只能相遇一次,如果在第1行,第n行,第1列,第m列相遇的话那么下一步两人将走入同一个房间或对方之前进入过的房间 { for(j=2; j<m; j++) { ans = max(ans,dp1[i-1][j]+dp2[i+1][j]+dp3[i][j+1]+dp4[i][j-1]);//因为相遇的房间不计入卡路里,所以将该点的四个角的dp式相加 ans = max(ans,dp1[i][j-1]+dp2[i][j+1]+dp3[i-1][j]+dp4[i+1][j]); } } printf("%lld\n",ans); } return 0; }