1 条题解
-
0
// 原矩阵大小最大 1000×1000,这里开 1005 long long a[1005][1005]; // 存储每个格子的数值 long long f[1005][1005][3]; // DP 状态,第三维 0/1/2 表示进入方式 // 将 f 数组初始化为一个非常小的负数(近似负无穷),表示不可达 memset(f, 0xcf, sizeof f); // 起点 (1,1) 无论从哪个方向“进入”,都只有它本身的值 // 第三维含义:0 = 从左边来,1 = 从上边来,2 = 从下边来 // 起点特殊处理,三个方向初始值均为 a[1][1] f[1][1][0] = f[1][1][1] = f[1][1][2] = a[1][1]; // 按列进行动态规划(因为右移是最终方向,以列为阶段) for (int j = 1; j <= m; j++) { // 第一遍:处理从左边进入(即同一列内从上往下)的状态 for (int i = 1; i <= n; i++) { // 状态0:从左边进入 (i,j) // 需要前一列 (i, j-1) 的任意状态,加上当前格子的值 if (j > 1) f[i][j][0] = max({f[i][j-1][0], f[i][j-1][1], f[i][j-1][2]}) + a[i][j]; // 状态1:从上方进入 (i,j) // 需要同一列上一行 (i-1, j) 从左边或上方进入的状态,但不能从下方(避免回头) if (i > 1) f[i][j][1] = max(f[i-1][j][0], f[i-1][j][1]) + a[i][j]; } // 第二遍:处理从下方进入(即同一列内从下往上)的状态 // 方向相反,从下往上更新 for (int i = n - 1; i >= 1; i--) { // 状态2:从下方进入 (i,j) // 需要同一列下一行 (i+1, j) 从左边或下方进入的状态 f[i][j][2] = max(f[i+1][j][0], f[i+1][j][2]) + a[i][j]; } } // 最终答案:到达终点 (n,m) 时,可以从左边、上方或下方进入,取最大值 cout << max({f[n][m][0], f[n][m][1], f[n][m][2]});
- 1
信息
- ID
- 711
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 8
- 已通过
- 1
- 上传者