更难的矩阵取数问题

来源:互联网 发布:有声照片软件 编辑:程序博客网 时间:2024/06/16 01:48

题目描述:

一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上。第1遍时只能向下和向右走,第2遍时只能向上和向左走。两次如果经过同一个格子,则该格子的奖励只计算一次,求能够获得的最大价值。
 
例如:3 * 3的方格。

1 3 3
2 1 3
2 2 1

能够获得的最大价值为:17。1 -> 3 -> 3 -> 3 -> 1 -> 2 -> 2 -> 2 -> 1。其中起点和终点的奖励只计算1次。


输入

第1行:2个数M N,中间用空格分隔,为矩阵的大小。(2 <= M, N <= 200)
第2 - N + 1行:每行M个数,中间用空格隔开,对应格子中奖励的价值。(1 <= A[i,j] <= 10000)

输出

输出能够获得的最大价值。

输入示例

3 3
1 3 3
2 1 3
2 2 1


输出示例

17


#include<cstdio>  #include<cstring>  #include<algorithm>  using namespace std;  #define inf 0x3f3f3f3f  #define maxn 201  int M[maxn][maxn];  int dp[maxn<<1][maxn][maxn];  int main()  {      int n,m,i,j,x1,x2;      scanf("%d%d",&m,&n);      for(i=0;i<n;++i)          for(j=0;j<m;++j)              scanf("%d",&M[i][j]);      memset(dp,0,sizeof(dp));      dp[0][0][0]=M[0][0];      for(i=1;i<n+m;++i)          for(x1=0;x1<n&&i-x1>=0;++x1)              for(x2=0;x2<n&&i-x2>=0;++x2)              {                  if(x1-1>=0&&x2-1>=0)                      dp[i][x1][x2]=max(dp[i][x1][x2],dp[i-1][x1-1][x2-1]+M[x1][i-x1]+(x1==x2?0:M[x2][i-x2]));                  if(x1-1>=0&&i-x2-1>=0)                      dp[i][x1][x2]=max(dp[i][x1][x2],dp[i-1][x1-1][x2]+M[x1][i-x1]+(x1==x2?0:M[x2][i-x2]));                  if(x2-1>=0&&i-x1-1>=0)                      dp[i][x1][x2]=max(dp[i][x1][x2],dp[i-1][x1][x2-1]+M[x1][i-x1]+(x1==x2?0:M[x2][i-x2]));                  if(i-x2-1>=0&&i-x1-1>=0)                      dp[i][x1][x2]=max(dp[i][x1][x2],dp[i-1][x1][x2]+M[x1][i-x1]+(x1==x2?0:M[x2][i-x2]));              }      printf("%d\n",dp[n+m-1][n-1][n-1]);      return 0;  }