1 //第一次遇到这种DP,看大牛的博客都是用最大流求解的。。。dp[k][i][j] 表示走k步,第一条路线横向走了i步,第二条路线横向走了j步,所获得的最大值。。 2 3 //转移方程也很好想 4 #include<stdio.h> 5 6 #include<string.h> 7 #define Max(x,y) (x>y?x:y) 8 9 int dp[60+2][30+2][30+2],map[30+2][30+2],n; 10 11 int max(int a,int b,int c,int d){ 12 return Max(a,Max(Max(b,c),d)); 13 } 14 15 int main(){ 16 while(~scanf("%d",&n)){ 17 for(int i=0;i<n;i++){ 18 for(int j=0;j<n;j++){ 19 scanf("%d",&map[i][j]); 20 } 21 } 22 memset(dp,0,sizeof(dp)); 23 for(int k=1;k<2*n-2;k++){ 24 for(int i=0;i<=k&&i<n;i++){ 25 for(int j=0;j<=k&&j<n;j++){ 26 if(i==j){ 27 continue; 28 } 29 int& res=dp[k][i][j]; 30 res=max(dp[k-1][i][j],dp[k-1][i-1][j],dp[k-1][i][j-1],dp[k-1][i-1][j-1]); 31 res+=map[i][k-i]+map[j][k-j]; 32 } 33 } 34 } 35 int ans=Max(dp[2*n-3][n-1][n-2],dp[2*n-3][n-2][n-1]); 36 ans+=map[0][0]+map[n-1][n-1]; 37 printf("%d ",ans); 38 } 39 }