题解:
就是找从 (1, 1 ) 到 ( n, n )的路径, 是代数和最大。
两条进程同时进行。
我们 设 步数 K, 因为路径不能重复, 所以当( x1 == x2 || y1 ==y2 ) 就跳过。
所以 动态 转移方程 为
dp ( k, x1, y1, x2, y2 ) = MAX ( dp ( k - 1, x1 - 1, y1, x2 - 1, y2 ), dp ( k - 1, x1 - 1, y1, x2, y2 - 1 ), dp ( k - 1, x1, y1 - 1, x2 - 1, y2 ), dp ( k - 1, x1, y1 - 1, x2, y2 - 1 ) ) + data ( x1, y1 ) + data ( x2, y2 );
因为
x + y = k,所以可以将为 3 维 动态方程
dp ( k, x1, x2 ) = MAX ( dp ( k - 1, x1, x2 ), dp ( k - 1, x1 - 1, x2 ), dp ( k - 1, x1, x2 - 1 ), dp ( k - 1, x1 - 1, x2 - 1 ) ) + data ( x1, k - x1 ) + data ( x2, k - x2 );
#include <stdio.h>
#include <string.h>
int n, data[31][31], dp[62][31][31], i, j, k;
int MAX ( int a, int b ) {
return a > b? a : b;
}
int maxx ( int a, int b, int c, int d ) {
return MAX ( MAX ( MAX ( a, b ), c ), d );
}
int main ( ) {
while ( scanf ( "%d", &n ) != EOF ) {
for ( i = 0; i < n; ++i )
for ( j = 0; j < n; ++j )
scanf ( "%d", &data[i][j] );
memset ( dp, 0, sizeof ( dp ) );
for ( k = 1; k < 2 * n - 2; ++k ) {
for ( i = 0; i <= k; ++i ) {
for ( j = 0; j <= k; ++j ) {
if ( i == j || i >= n || j >= n ) continue;
dp[k][i][j] = maxx ( dp[k - 1][i][j], dp[k - 1][i - 1][j], dp[k - 1][i][j - 1], dp[k - 1][i - 1][j - 1] );
dp[k][i][j] += data[i][k - i] + data[j][k - j];
}
}
}
dp[k][n - 1][n - 1] = MAX ( dp[k - 1][n - 2][n - 1], dp[k - 1][n - 1][n - 2] ) + data[n - 1][n - 1] + data[0][0];
printf ( "%d\n", dp[k][n - 1][n - 1] );
}
}