解法一较为基础,便于理解
引用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位。