首页 > 其他分享 >P7074 [CSP-J2020] 方格取数 题解

P7074 [CSP-J2020] 方格取数 题解

时间:2024-10-23 22:32:54浏览次数:1  
标签:int 题解 ll dfs 取数 max P7074 1005 include

动态规划 dp

方格取数类似于数字三角形,均可以使用动态规划直接秒杀.

但此题有 $3$ 个方向:上、右、下.所以可以定义一个三维数组 dp 数组.

假设 $f_{i, j, 1}$ 是从右、上方到达 $(i,j)$ 的和的最大值.

又有 $f_{i, j, 0}$ 是从右、下方到达 $(i,j)$ 的和的最大值.

我们可以先确定目标:$f_{n,m,1}$.为什么不是 $f_{n,m,0}$ 呢?因为小熊不可能从 $(n,m)$ 的下方到达终点.

状态转移

$f_{i,j,0} = max(f_{i+1,j,0}, max(f_{i,j-1,0}, f_{i,j-1,1})) + a_{i,j}$.

$f_{i,j,1} = max(f_{i-1,j,1}, max(f_{i,j-1,0}, f_{i,j-1,1})) + a_{i,j}$.

$a_{i,j}$ 表示当前各自的值.

当方向为 $0$ 时,说明小熊要往下方走,或者是右边走,但往右边走不管方向是 $0$ 或 $1$

均可以走.所以三者要取 $max$ 值.最后加上当前各自的值.

方向为 $1$ 时同理.

初始化

给 $f$ 数组中的格子赋一个较小的初值,类似于 $-10^{18}$.

然后将小熊的起点,即坐标 $(1,1)$ 的初值赋值如下:

f[1][1][0] = f[1][1][1] = a[1][1]

注意点

要开 long long!!!.

代码

这里使用类似于记忆化搜索的方式.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long ll;
const ll min_ll = -1e18;
int n, m;
ll a[1005][1005], f[1005][1005][2];

ll dfs(int x, int y, int from) {
    // 出界了
	if (x < 1 || x > n || y < 1 || y > m) return min_ll;
    // 有值了,返回
	if (f[x][y][from] != min_ll) return f[x][y][from];
    // 状态转移
	if (from == 0) f[x][y][from] = max(dfs(x + 1, y, 0), max(dfs(x, y - 1, 0), dfs(x, y - 1, 1))) + a[x][y];
	else f[x][y][from] = max(dfs(x - 1, y, 1), max(dfs(x, y - 1, 0), dfs(x, y - 1, 1))) + a[x][y];
	return f[x][y][from]; // 希望得到的结果
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			scanf("%lld", &a[i][j]);
			f[i][j][0] = f[i][j][1] = min_ll; // 赋初值
		}
	}
	f[1][1][0] = f[1][1][1] = a[1][1]; // 赋初值
	printf("%lld", dfs(n, m, 1)); // 目标
	return 0;
}

标签:int,题解,ll,dfs,取数,max,P7074,1005,include
From: https://www.cnblogs.com/panda-lyl/p/18498509

相关文章

  • P7912 [CSP-J 2021] 小熊的果篮 题解
    是模拟吗?其实是的,虽然$1\len\le2\times10^5$,但是队列是个好东西.我们定义一个结构体,来存放每一个块的信息,包括类型、起点、终点,将它们放入队列当中,再使用基于广搜的思想,先处理,再合并,所以需要用到$2$个队列.注意点数据中可能会有块的类型全是$1$,或者全是$0$的情况......
  • P7071 [CSP-J2020] 优秀的拆分 题解
    二进制"优秀的拆分"如果存在,则代表$n$的二进制最低位不是$1$.$\because2^0=1$$\therefore$当$n$的二进制最低位为$1$时,不存在优秀的拆分.即$n$不是奇数.上述条件判断完后,就可以从$2$的$30$次方开始模拟(int的上限是$2^{31}-1$).代码#include<iostream>......
  • P7072 [CSP-J2020] 直播获奖 题解
    暴力使用$\Theta(n^2)$的时间复杂度来解决这题大约能拿到$60pts$.即枚举$p$,再枚举每个选手的分数.正解桶是个好东西.我们开一个桶,记录当前分数有多少人.然后计算获奖人数,分数从大到小进行枚举,直到当前人数$\ge$获奖人数.代码#include<iostream>#include<cstdio>#i......
  • [CSP-J2020] 表达式 题解
    短路这道题目中所含的运算符只有3个:与、或、非.在与运算和或运算中有2个性质.进行与运算时,若其中有一个值为0,则这个运算的结果就为0,即无需判断另1个数是否是0或1.进行或运算时,若其中有一个值为1,则这个运算的结果就为1,也无需判断另一个数是否是0或1.表达式树根据短路的性......
  • 题解 SS241023D【数颜色】/ ZROI3029【静态邻域数颜色】
    静态邻域数颜色-题目-ZhengruiOnlineJudge题目描述静态树上邻域数颜色。给一棵\(n\)个点的无根树,第\(i\)个点颜色为\(a_i\)。有\(q\)次询问,每次询问如下:给定\(x,d\),考虑所有距离\(x\)不超过\(d\)的点,求有多少种不同的颜色。形式化地,给定\(x,d\),求\(|\{a......
  • 题解 P5326【[ZJOI2019] 开关】/ SS241023B【判断题】
    已经沦落为可以随便搬进模拟赛的模板题了。。。题目描述当前有\(n\)道判断题,初始全选的错。初始给出每道题的正确答案,设\(0\)表示错,\(1\)表示对。每道题有一个参数\(p_i\),每轮会以\(\frac{p_i}{\sum_{j=1}^{n}p_j}\)的概率选择第\(i\)道题并修改(flip)这道题的答......
  • [COCI2009-2010#4] PALACINKE 题解
    前言题目链接:洛谷。题意简述\(n\)个点,\(m\)条边。每条边上有商店,经过一条边花费\(1\)单位时间,如果在边上的商店购物,额外花费\(1\)单位时间。需要购买\(4\)种物品,每个商店售出\(1\sim4\)种物品不等。请问,在\(T\)个单位时间内,从\(1\)出发购物,得到这\(4\)种物品......
  • [算法题解] Codeforces round 979 --D. QED's Favorite Permutation
    题目链接:https://codeforces.com/contest/2030/problem/D题目:题解:FavotitePermutation即每个数满足i=p[i];此题中,p数组每次询问后保持不变,s根据询问而改变。因此每次需要进行交换的数的位置是相同的,只需要检验s变更后,操作能否满足交换需求与否。故创建需数组need,预处理nee......
  • 题解:CF1225E Rock Is Push
    很玄妙的一道dp题。HintAnalysis首先你要确保你会做当石头没有/固定的情况,这道题其实也是dp。考虑石头带来的影响,唯一的作用就是限制你的移动,比方说你下面有\(3\)块石头,由于只能向右或向下移动,你实际上往下只能走到当前列第\(n-3\)行。于是对于石头的处理,设\(rs[i][j......
  • 题解:P11215 【MX-J8-T3】水星湖
    依旧是模拟赛赛题。HintAnalysis首先你注意到两棵相邻的树是一定不会死的,所以可能会死的只有自己种下去的树,队列维护。接着考虑对于每个位置,\(\text{bfs}\)维护一个最小的长出树的时间\(vis[i][j]\),最后暴力统计答案即可。具体细节看注释。Code#include<bits/stdc++.h>......