- gf24118 的博客
sol・方格取数
- @ 2026-10-3 11:19:29
#P7074 [CSP-J 2020] 方格取数
[返回题解]
题目速览
题目描述
设有 的方格图,每个方格中都有一个整数。现有一只小熊,想从图的左上角走到右下角,每一步只能向上、向下或向右走一格,并且不能重复经过已经走过的方格,也不能走出边界。小熊会取走所有经过的方格中的整数,求它能取到的整数之和的最大值。
输入格式
第一行有两个整数 。
接下来 行每行 个整数,依次代表每个方格中的整数。
输出格式
一个整数,表示小熊能取到的整数之和的最大值。
输入输出样例 #1
输入 #1
3 4
1 -1 3 2
2 -1 4 -1
-2 2 -3 -1
输出 #1
9
输入输出样例 #2
输入 #2
2 5
-1 -1 -3 -2 -7
-2 -1 -4 -1 -2
输出 #2
-10
说明/提示
样例 1 解释
样例 2 解释
数据规模与约定
- 对于 的数据,。
- 对于 的数据,。
- 对于 的数据,。
- 对于 的数据,。方格中整数的绝对值不超过 。
一道 普及+/提高− 的题
-
定义状态
...,从图的左上角走到右下角,每一步只能向上、向下或向右走一格,并且不能重复经过已经走过的方格,也不能走出边界...
由↑可知,这只小熊在同一列选择向上走时,不能再向下走,反之同理。所以可以这样定义状态:
定义状态
定义为在第列中,路径从该列的上方最终到达 时的最大和。
定义为在第列中,路径从该列的下方最终到达时的最大和。
定义为到达坐标时,所能获得的最大和。
-
初始化
因为小熊从出发,所以在第一列只能往下走。
代码
for(int i=1;i<=n;i++) s+=a[i][1],dp[i][1]=s,sh[i][1]=MINN,xi[i][1]=s;
-
状态转移方程
状态转移方程
特殊:
-
答案
答案
代码部分
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=1e3+5,MINN=INT_MIN;
ll s,dp[MAXN][MAXN],a[MAXN][MAXN],sum,sh[MAXN][MAXN],xi[MAXN][MAXN],n,m;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++) s+=a[i][1],dp[i][1]=s,sh[i][1]=MINN,xi[i][1]=s;//初始化
for(int j=2;j<=m;j++){
for(int i=1;i<=n;i++) sum=dp[i][j-1],sum=(i>1 ? max(sum,sh[i-1][j]):dp[i][j-1]),sh[i][j]=sum+a[i][j];
for(int i=n;i>=1;i--) sum=dp[i][j-1],sum=(i<n ? max(sum,xi[i+1][j]):dp[i][j-1]),xi[i][j]=sum+a[i][j];
for(int i=1;i<=n;i++) dp[i][j]=max(sh[i][j],xi[i][j]);
}
cout<<dp[n][m];
return 0;
}
//fish code

