来回可以看作从(1,1)出发到(n,n)的两条不相交的路径
//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])
//k为步数
//k与x1,y1有关,可以降到三维
//多决策dp //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]) //k为步数 //k与x1,y1有关,可以降到三维 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <stack> #include <queue> using namespace std; const int inf = (1<<31)-1; const int MAXN = 3e1+10; int dp[2*MAXN][MAXN][MAXN]; int a[MAXN][MAXN]; int t1[2],t2[2]; int main() { int n; while(~scanf("%d",&n)){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d",&a[i][j]); } } memset(dp,0,sizeof(dp)); // dp[0][1][1] = a[1][1]; for(int i=1;i<=2*n-3;i++){ for(int j=1;j<=i+1&&j<=n-1;j++){//x1满足 if(i+2-j>n)continue;//y1满足 for(int k=j+1;k<=i+1&&k<=n;k++){ if(i+2-k>n-1)continue; t1[0] = j; t1[1] = j-1; t2[0] = k; t2[1] = k-1; for(int l=0;l<2;l++){ for(int r=0;r<2;r++){ if(t1[l]==t2[r])continue; dp[i][j][k] = max(dp[i][j][k],dp[i-1][t1[l]][t2[r]]); } } dp[i][j][k] += a[j][i+2-j]+a[k][i+2-k]; /* cout<<i<<" "<<j<<" "<<k<<" "<<dp[i][j][k]<<endl; cout<<"debug"<<endl;*/ } } } dp[2*n-2][n][n] = dp[2*n-3][n-1][n] + a[n][n]; cout<<dp[2*n-2][n][n]+a[1][1]<<endl; } //cout << "Hello world!" << endl; return 0; }