专栏文章
题解:P7074 [CSP-J2020] 方格取数
P7074题解参与者 33已保存评论 41
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 41 条
- 当前快照
- 1 份
- 快照标识符
- @miqo8caf
- 此快照首次捕获于
- 2025/12/04 08:01 3 个月前
- 此快照最后确认于
- 2025/12/04 08:01 3 个月前
solution
方格取数,经典的动态规划问题,但有所不同。这里可以向上走,也要求不能重复取数。对于这个不同也很好处理,只需要多开一维记录当前格子从哪个方向转移,就可以避免类似刚从上面过来又往上走的问题。
所以,我们设 表示取数到 时的最大值, 表示从左转过来的, 表示从上转过来的, 表示从下转过来的。
绿色是当前格子,绿色根据 是由黄色转移到的,黄色是由红色转移得到,下面是对应的三种情况。
- 时,。
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
f[i][j][0]=max({f[i][j-1][0], f[i][j-1][1], f[i][j-1][2]})+a[i][j];

- 时,。
for (int i=2; i<=n; i++)
for (int j=1; j<=m; j++)
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--)
for (int j=1; j<=m; j++)
f[i][j][2]=max(f[i+1][j][0], f[i+1][j][2])+a[i][j];

因为有负数,所以实现的时候要注意初值设极小值。
code
CPP#include <bits/stdc++.h>
using namespace std;
long long n, m, a[1005][1005], f[1005][1005][3];
int main () {
cin >> n >> m;
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
cin >> a[i][j];
memset(f, -0x3f, sizeof f);
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++)
f[i][j][0]=max({f[i][j-1][0], f[i][j-1][1], f[i][j-1][2]})+a[i][j];
for (int i=2; i<=n; i++)
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--)
f[i][j][2]=max(f[i+1][j][0], f[i+1][j][2])+a[i][j];
}
cout << max({f[n][m][0], f[n][m][1], f[n][m][2]});
return 0;
}
相关推荐
评论
共 41 条评论,欢迎与作者交流。
正在加载评论...