P7074 [CSP-J 2020] 方格取数

思路来自大佬:Indjy

学校老师居然把这个题放在区间DP里面但是我没想到该怎样用,标签里也没有,那就用暴力DP来做吧。

题目大意#

有一个n×m的方格,可以向下,向上,向右走一格,而且不能走重复的格子。

现在要求在一条路径中和最大的走法。

解题思路#

因为这个题目比较扯,是向上、向下、向右走,不是我们常见的向下、向左、向右,因此我们想到了一种神奇的方法:

将整个表格顺时针旋转90度

这下就好办了:变成了向下、向左、向右的走法了。

看到这个走法你会想到什么?是不是感觉很熟悉?

没错,那就是数字三角形的走法。因此,这一道普及+/提高-的题一下子变成了普及-。

需要的数组及变量#

dp[N][N][2]:顾名思义就是存动态规划。但是,和数字三角形不一样,我们需要多一维来存是向左还是向右。

a[N][N]:存原来的数据(表格)。

nm:题目所给。

设计代码#

DP方程#

我们既然已经知道了DP方程和数字三角形很类似,那就直接上吧。

我们设dp[i][j][0/1]表示现在的位置是(i,j),0表示向左,1表示向右。

向下走#

向下走和之前来的方向没有关系,所以就是看左边还是右边最大然后直接转移。那么方程就是:

dp[i][j][0]=max(dp[i1][j][0],dp[i1][j][1])+a[i][j]

dp[i][j][1]=max(dp[i1][j][0],dp[i1][j][1])+a[i][j]

向左走#

顾名思义,就是看当前的大还是从左边转移的大。于是方程就是:

dp[i][j][0]=max(dp[i][j][0],dp[i][j1][0]+a[i][j])

向右走#

和向左走一样,方程就是:

dp[i][j][1]=max(dp[i][j][1],dp[i][j+1][1]+a[i][j])

两个方向要分别转移,向左要倒序,向右要正序。

完整代码#

#include <bits/stdc++.h>
#define int long long 
#define inf 0x7f7f7f7f7f7f7f
using namespace std;
const int N = 1e3 + 10;
int dp[N][N][2], a[N][N];
int n, m;
int read() {
	int x = 0, w = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')
			w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return x * w;
}
signed main() {
	n = read(); m = read();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			a[j][i] = read();
	swap(n, m);
	memset(dp, -inf, sizeof dp);
	dp[1][1][0] = dp[1][1][1] = a[1][1];
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (i != 1) {
				dp[i][j][0] = max(dp[i][j][0], max(dp[i - 1][j][0], dp[i - 1][j][1]) + a[i][j]);
				dp[i][j][1] = max(dp[i][j][1], max(dp[i - 1][j][0], dp[i - 1][j][1]) + a[i][j]);
			}
			if (j != 1)
				dp[i][j][0] = max(dp[i][j][0], dp[i][j - 1][0] + a[i][j]);
		}
		for (int j = m; j >= 1; j--) 
			if (j != m)
				dp[i][j][1] = max(dp[i][j][1], dp[i][j + 1][1] + a[i][j]);
	}
	cout << max(dp[n][m][0], dp[n][m][1]) << endl;
	return 0;
}

给个赞吧!

作者:GTGumiiL

出处:https://www.cnblogs.com/GTGumiiL/p/17104491.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

记得关注呀~

posted @   煎饼Li  阅读(164)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu