蓝桥杯真题:跳跃

蓝桥杯真题:跳跃_第1张图片

蓝桥杯真题:跳跃_第2张图片

输入输出样例

示例 1

输入

3 5
-4 -5 -10 -3 1
7 5 -9 3 -10
10 -2 6 -10 -4

输出

15

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

这题是很典型的dp问题。画图可知,一个点可以到达以它为顶点的一个等腰直角三角形的区域位置,长这样:

蓝桥杯真题:跳跃_第3张图片

 其中圆圈是出发点,方形是可以走到的点

那么一个点可以从哪里来呢?容易想到是这样的:

蓝桥杯真题:跳跃_第4张图片

所以对每个点,我们的任务是挑选出上图中圆圈里边的最大值,然后与当前的值相加就好了,自底向上的代码实现如下所示:

#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<

你可能感兴趣的:(动态规划,蓝桥杯,职场和发展)