原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4826
/******************************************************************************
* Author: Tlight
* URL: http://blog.csdn.net/tlight
* Title : Labyrinth
* Source: hdu 4826
* Hint: DP
******************************************************************************/
#include "stdio.h"
#define INF 0x7fffff
#define MAX_M 105
#define MAX_N 105
int map[MAX_M][MAX_N]; // 每个格子的金币数
int dp[MAX_M][MAX_N]; // 走到当前i行j列得到的最多金币数,到达当前格子有三种,从上面格子向下走,从左边格子向右走,从下面格子向上走
int down2up[MAX_M];
int up2down[MAX_M];
int MAX(int a, int b)
{
return a > b ? a : b;
}
int main()
{
freopen("hdu4826_input.txt", "r", stdin);
int T, tc;
scanf("%d", &T);
for (tc = 1; tc <= T; tc++)
{
int m, n;
int i, j;
scanf("%d %d", &m, &n);
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
scanf("%d", &map[i][j]);
// 因为起点是左上角,因此计算第一列的dp值, 只能从上往下计算
dp[1][1] = map[1][1];
for (i = 2; i <= m; i++)
{
dp[i][1] = dp[i - 1][1] + map[i][1];
}
// 从第二列开始, 有两种计算方式,从上到下和从下到上
for (j = 2; j <= n; j++)
{
// up2down,临时计算出从上向下走能获得的最多金币数
up2down[0] = -INF;
for (i = 1; i <= m; i++)
up2down[i] = MAX(up2down[i - 1], dp[i][j - 1]) + map[i][j];
// down2up,临时计算出从下往上走能获得的最多金币数
down2up[m+1] = -INF;
for (i = m; i >= 1; i--)
down2up[i] = MAX(down2up[i + 1], dp[i][j - 1]) + map[i][j];
// 比较上面两种走法,取最大的作为最后的结果
for (i = 1; i <= m; i++)
{
dp[i][j] = MAX(up2down[i], down2up[i]);
}
}
printf("Case#%d:\n", tc);
printf("%d\n", dp[1][n]);
}
return 0;
}