示例 1
输入
3 5
-4 -5 -10 -3 1
7 5 -9 3 -10
10 -2 6 -10 -4
输出
15
这题是很典型的dp问题。画图可知,一个点可以到达以它为顶点的一个等腰直角三角形的区域位置,长这样:
其中圆圈是出发点,方形是可以走到的点
那么一个点可以从哪里来呢?容易想到是这样的:
所以对每个点,我们的任务是挑选出上图中圆圈里边的最大值,然后与当前的值相加就好了,自底向上的代码实现如下所示:
#include
using namespace std;
int dx[]={0,0,0,-1,-1,-1,-2,-2,-3};
int dy[]={-1,-2,-3,0,-1,-2,0,-1,0};
int main()
{
// 请在此输入您的代码
int n,m;
scanf("%d%d",&n,&m);
vector> dp(n,vector(m,INT_MIN));
for(int i=0;i=0 && y>=0)
{
value=max(dp[x][y],value);
}
}
if(value!=INT_MIN) dp[i][j]+=value;
}
}
cout<
当然,感谢题解部分提供的递归写法:
#include
using namespace std;
int n,m;
int dp(vector>&grid,vector>&memo,int x,int y){
int dx[] = {0,0,0,-1,-1,-1,-2,-2,-3};
int dy[] = {-1,-2,-3,0,-1,-2,0,-1,0};
//base case:
if(x<0||y<0)return INT_MIN;
if(x==0&&y==0)return grid[0][0];
if(memo[x][y]!=INT_MIN)return memo[x][y];
//condition transfer:
int temp = INT_MIN;
for(int i=0;i<9;i++){
int q = dp(grid,memo,x+dx[i],y+dy[i]);
if(q==INT_MIN)continue;
temp = max(temp,q);
}//备忘录memo更新
memo[x][y] = temp + grid[x][y];
return memo[x][y];
}
int main()
{
cin>>n>>m;
//创建并赋值grid(方格)数组
vector>grid(n,vector(m));
for(int i=0;i>grid[i][j];
}
}
//调用dp函数解决问题:
vector> memo(n,vector(m,INT_MIN));
cout<