【解题报告】洛谷P7074 方格取数
题目链接
https://www.luogu.com.cn/problem/P7074
思路
这道题目就是从 (1,1) 开始随便走,不走重复的,只能向上向右和向下走一个,走到 (n,m) ,问可以取到的最大是多少
乍一眼看过去跟之前的方格取数很像,实际上不一样
因为这里可以从下面转移过来,怎么办呢?
我们设 f[i][j][0/1] 表示从 (1,1)→(i,j) 的最大值 ,其中 0,1 分别表示从上方走过来,从下方走过来
于是我们进行一个记忆化搜索,就可以过了
这里重要的点在于设置状态,因为这道题目主要与众不同的地方就在于可以从下方转移过来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #define int long long using namespace std; const int maxn=1005; const int INF=1e9; int n,m; int a[maxn][maxn]; int f[maxn][maxn][5]; bool vis[maxn]; int dfs(int i,int j,int from) { if(i<1||j<1||i>n||j>m) return -INF; if(f[i][j][from]!=-INF) return f[i][j][from]; if(from==0) f[i][j][from]=max(dfs(i+1,j,0),max(dfs(i,j-1,0),dfs(i,j-1,1)))+a[i][j]; else f[i][j][from]=max(dfs(i-1,j,1),max(dfs(i,j-1,0),dfs(i,j-1,1)))+a[i][j]; return f[i][j][from]; } signed 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++) { for(int j=1;j<=m;j++) f[i][j][0]=f[i][j][1]=-INF; } f[1][1][0]=f[1][1][1]=a[1][1]; cout<<dfs(n,m,1)<<'\n'; return 0; }
|