http://acm.bjtu.edu.cn/vjudge/problem/viewProblem.action?id=1815
经典的双线程dp,dp[i][x1][y1][x2][y2]表示走i步在(x1,y1),(x2,y2)两点处取得的和的最大值,假设矩阵从0-n-1,有i=x+y,五维转化成三维。
代码中用了滚动数组,不过在这里意义不大
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std ; int map[31][31],dp[3][31][31] ; int MAX(int a,int b,int c,int d) { a=max(a,b) ; c=max(c,d) ; a=max(a,c) ; return a ; } int main() { int n ; while(~scanf("%d",&n)) { int i,j,k ; for(i=0;i<n;i++) for(j=0;j<n;j++) scanf("%d",&map[i][j]) ; memset(dp,0,sizeof(dp)) ; int temp=2*n-2 ; for(i=1;i<temp;i++) for(j=0;j<=i;j++) for(k=0;k<=i;k++) { if(j==k||j==n||k==n) continue ; dp[i&1][j][k]=MAX(dp[(i-1)&1][j-1][k],dp[(i-1)&1][j][k-1],dp[(i-1)&1][j-1][k-1],dp[(i-1)&1][j][k]) ; dp[i&1][j][k]+=map[j][i-j]+map[k][i-k] ; } dp[i&1][n-1][n-1]=max(dp[(i-1)&1][n-2][n-1],dp[(i-1)&1][n-1][n-2])+map[0][0]+map[n-1][n-1] ; printf("%d\n",dp[i&1][n-1][n-1]) ; } return 0 ; }