跳跃

本文介绍了两种方法求解从(1,1)到(n,m)的二维数组中,每个单元格加上其周围特定范围内单元格的最大值的问题。解法一是基础的迭代方式,解法二是利用动态规划的思路,避免了重复计算。还提到使用长整型处理可能的溢出问题。
摘要由CSDN通过智能技术生成

解法一较为基础,便于理解

引用fiand函数被查找最大值,并进行更新

//解法一
#include <stdio.h>
#include <stdlib.h>

int b[105][105];
int find_max(int x,int y){
  int max=0;
  for(int i=x;i>=1;i--){
    for(int j=y;j>=1;j--){
      if(!(x==i&&y==j)&&(x-i+y-j)<=3&&max<b[i][j]){
        //同时满足的三个条件
        //1.不原地踏步2.每次跳跃在距离范围之内3.比当前max更大时才更新max
        max=b[i][j];
      }
    }
  }
  return max;
}

int main(int argc, char *argv[])
{
  // 请在此输入您的代码
  int n,m;
  scanf("%d %d",&n,&m);
  int i,j;
  for(i=1;i<=n;i++){
    for(j=1;j<=m;j++){
      scanf("%d",&b[i][j]);
    }
  }
  for(i=1;i<=n;i++){
    for(j=1;j<=m;j++){
      b[i][j]+=find_max(i,j);
    }
  }
  printf("%d",b[n][m]+b[1][1]);
  return 0;
}

解法二

  由题意可知,我们需要求解从(1,1)到(n,m)的权值之和最大的路径

  即此题是最值求解类问题

  那么,我们可以考虑采用动态规划(DP)进行问题的求解。

  DP需要注意以下两个条件:

  1.状态表示

    g[i][j]表示到达此点的最大权值

  2.状态转移方程

    ans=max(ans,g[i+X[k]][j+Y[k]])表示可以到达此点的所有点权值之和最大值

    g[i][j]+=ans表示更新后的该点权值

  求解时每一步都选取最优解,只需进行一次点的权值更新。

//解法二
#include<stdio.h>
#include<limits.h>

#define maxn 1005

int g[105][maxn];
long long n, m;
int X[9] = {0,0,0,-1,-1,-1,-2,-2,-3};
int Y[9] = {-3,-2,-1,-2,-1,0,-1,0,0};

int main()
{
    scanf("%lld %lld", &n, &m);
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            scanf("%d", &g[i][j]);
            int ans = INT_MIN;
            for(int k = 0; k < 9; k++)
            {
                if(i + X[k] >= 1 && j + Y[k] >= 1)
                    ans = (ans > g[i + X[k]][j + Y[k]]) ? ans : g[i + X[k]][j + Y[k]];
            }
            if(ans != INT_MIN) g[i][j] += ans;
        }
    }
    printf("%d\n", g[n][m]);
    return 0;
}

引用MR_jie1用户:

int占4字节32位,根据二进制编码的规则,
INT_MAX = 2^31-1=2147483647
INT_MIN= -2^31=-2147483648
C/C++中,所有超过该限值的数,都会出现溢出,出现warning,但是并不会出现error。如果想表示的整数超过了该限值,可以使用长整型long long 占8字节64位。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值