Description
设有N*N的方格图,我们将其中的某些方格填入正整数,
而其他的方格中放入0。
某人从图得左上角出发,可以向下走,也可以向右走,直到到达右下角。
在走过的路上,他取走了方格中的数。(取走后方格中数字变为0)
此人从左上角到右下角共走3次,试找出3条路径,使得取得的数总和最大。
Input
第一行:N (4<=N<=50)
接下来一个N*N的矩阵,矩阵中每个元素不大于9,不小于0
Output
一行,表示最大的总和。
Sample Input
4
1234
2134
1234
1324
Sample Output
39
分析
这道题是 方格取数 的加强版,从数据范围来看,开六维数组是肯定会爆掉的,所以我们考虑优化。
和方格取数一样的,我们认为三条路是同时开始找的。
状态设计利用x + y = i + 2(i 为步数,x,y为坐标),可以设计成:f(i, x1, x2, x3),y1, y2, y3可以用状态中的 i 和对应的横坐标算出来。
于是乎就有了状态转移方程:
int y1 = min(i + 2 - x1, n), y2 = min(i + 2 - x2, n), y3 = min(i + 2 - x3, n);
int a = max(dp[i - 1][x1 - 1][x2][x3], dp[i - 1][x1][x2 - 1][x3]);
int b = max(dp[i - 1][x1][x2][x3 - 1], dp[i - 1][x1 - 1][x2 - 1][x3]);
int c = max(dp[i - 1][x1 - 1][x2][x3 - 1], dp[i - 1][x1][x2 - 1][x3 - 1]);
int d = max(dp[i - 1][x1][x2][x3], dp[i - 1][x1 - 1][x2 - 1][x3 - 1]);
dp[i][x1][x2][x3] = max(max(a, b), max(c, d)) + (k[x1][y1] + k[x2][y2] + k[x3][y3]);
//八条路径
当然,和方格取数一样的,我们要对重复计算