记一次动态规划的采坑之旅, 741摘樱桃 https://leetcode.cn/problems/cherry-pickup/description/

首次看题目时,发现是困难。立马想到了,动态规划。

再看题目, 摘樱桃,还要返回摘两次,求摘最多的樱桃。

大脑第一反应就是:

先使用动态规划,找到 0 0 到 n-1 n-1处走过的最大樱桃, 并记录路径path。

然后根据路径path,将摘过的樱桃置为0,表示已经被摘过了。 然后再次摘樱桃。

两次摘过的樱桃之和就是目标的结果。

嗯,应该是,那就开写。

func cherryPickup(grid [][]int) int {ans := 0n := len(grid)dp := make([][]int, 0)for i := 0; i < n; i++ {dp = append(dp, make([]int, n))}// 1 表示上一个路径是 上// 2 表示上一个路径是 左path := make([][]int, 0)for i := 0; i < n; i++ {path = append(path, make([]int, n))}// 记录首次dp的轨迹,开始第一次摘for i := 0; i < len(grid); i++ {for j := 0; j < len(grid[0]); j++ {if i == 0 && j == 0 {dp[0][0] = grid[0][0]continue}if grid[i][j] == -1 {dp[i][j] = -1continue}if (i - 1 < 0 || grid[i-1][j] == -1 || dp[i-1][j] == -1) && (j - 1 < 0 || grid[i][j-1] == -1 || dp[i][j-1] == -1) {dp[i][j] = -1continue}if i - 1 < 0 || grid[i-1][j] == -1 || dp[i-1][j] == -1 {dp[i][j] = dp[i][j-1] + grid[i][j]path[i][j] = 2continue}if j - 1 < 0 || grid[i][j-1] == -1 || dp[i][j-1] == -1 {dp[i][j] = dp[i-1][j] + grid[i][j]path[i][j] = 1continue}if dp[i][j-1] > dp[i-1][j] {path[i][j] = 2dp[i][j] = dp[i][j-1] + grid[i][j]} else {path[i][j] = 1dp[i][j] = dp[i-1][j] + grid[i][j]}}}ans += dp[n-1][n-1]if ans == -1 {return 0}// 回溯路径, 清理已经被摘过的樱桃ii, jj := n-1, n-1for path[ii][jj] != 0 {grid[ii][jj] = 0if path[ii][jj] == 1 {ii--} else {jj--}}// 第二次摘樱桃grid[0][0] = 0dp = make([][]int, 0)for i := 0; i < n; i++ {dp = append(dp, make([]int, n))}for i := 0; i < len(grid); i++ {for j := 0; j < len(grid[0]); j++ {if i == 0 && j == 0 {dp[0][0] = grid[0][0]continue}if grid[i][j] == -1 {dp[i][j] = -1continue}if (i - 1 < 0 || grid[i-1][j] == -1 || dp[i-1][j] == -1) && (j - 1 < 0 || grid[i][j-1] == -1 || dp[i][j-1] == -1) {dp[i][j] = -1continue}if i - 1 < 0 || grid[i-1][j] == -1 || dp[i-1][j] == -1 {dp[i][j] = dp[i][j-1] + grid[i][j]path[i][j] = 2continue}if j - 1 < 0 || grid[i][j-1] == -1 || dp[i][j-1] == -1 {dp[i][j] = dp[i-1][j] + grid[i][j]path[i][j] = 1continue}if dp[i][j-1] > dp[i-1][j] {path[i][j] = 2dp[i][j] = dp[i][j-1] + grid[i][j]} else {path[i][j] = 1dp[i][j] = dp[i-1][j] + grid[i][j]}}}// 将两次摘的樱桃数相加return ans + dp[n-1][n-1]
}

最后发现通过 53/59 , 差一点点点点。 其实差很多。

通过研究这个未通过的案例, 发现我虽然2次摘樱桃都是最大值, 但并不能证明最终采摘的樱桃数是最大的。

最后瞄了一眼答案, 来回摘2次樱桃数最多,又不能重复摘, 那找两个人同时摘不就好了吗。 

附上leetcode标准答案

func cherryPickup(grid [][]int) int {n := len(grid)f := make([][][]int, n*2-1)for i := range f {f[i] = make([][]int, n)for j := range f[i] {f[i][j] = make([]int, n)for k := range f[i][j] {f[i][j][k] = math.MinInt32}}}f[0][0][0] = grid[0][0]for k := 1; k < n*2-1; k++ {for x1 := max(k-n+1, 0); x1 <= min(k, n-1); x1++ {y1 := k - x1if grid[x1][y1] == -1 {continue}for x2 := x1; x2 <= min(k, n-1); x2++ {y2 := k - x2if grid[x2][y2] == -1 {continue}res := f[k-1][x1][x2] // 都往右if x1 > 0 {res = max(res, f[k-1][x1-1][x2]) // 往下,往右}if x2 > 0 {res = max(res, f[k-1][x1][x2-1]) // 往右,往下}if x1 > 0 && x2 > 0 {res = max(res, f[k-1][x1-1][x2-1]) // 都往下}res += grid[x1][y1]if x2 != x1 { // 避免重复摘同一个樱桃res += grid[x2][y2]}f[k][x1][x2] = res}}}return max(f[n*2-2][n-1][n-1], 0)
}func min(a, b int) int {if a > b {return b}return a
}func max(a, b int) int {if b > a {return b}return a
}作者:力扣官方题解
链接:https://leetcode.cn/problems/cherry-pickup/solutions/1656418/zhai-ying-tao-by-leetcode-solution-1h3k/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/670356.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

okcc最新版本会被盗打吗?

OKCC是一款智能外呼系统&#xff0c;它提供了多种安全措施来防止系统被盗打。以下是一些关键的安全配置和管理措施&#xff1a; 立即挂失SIM卡&#xff1a;一旦发现OKCC系统被盗打&#xff0c;应立即联系运营商进行SIM卡的挂失&#xff0c;以阻止盗打者继续使用您的号码进行通信…

软件设计师-应用技术-数据流图题1

基础知识及技巧&#xff1a; 0. 概念&#xff1a; 在结构化分析中&#xff0c;数据流图用来记录系统中的数据和数据在特定的过程中的流动&#xff0c;即数据如何被采集、处理、保存和使用的(围绕信息系统的功能)。 1. 元素实例&#xff1a; 补充知识&#xff1a;** 外部实体…

Unreal Engine插件打包技巧

打开UE工程&#xff0c;点击编辑&#xff0c;选择插件&#xff0c;点击"打包"按钮&#xff0c;选择输出目录UE4.26版本打包提示需要VS2017问题解决 1&#xff09;用记事本打开文件【UE4对应版本安装目录\Epic Games\UE_4.26\Engine\Build\BatchFiles\RunUAT.bat】 2&…

连锁收银系统总仓到门店库存调拨操作教程

1、进入系统后台&#xff0c;系统后台登录网址&#xff1a; 2、点击商品>门店调拨 3、选择调出仓库和调入门店 4、可选择添加商品逐个进行调拨&#xff0c;也可以批量导入需要调拨的商品 然后点击确定。 5、新增调拨后&#xff0c;系统会显示“待出库”状态 6、仓库已经准备…

WES-100B液晶数显式液压万能试验机

一、简介 主机为两立柱、两丝杠、油缸下置式&#xff0c;拉伸空间位于主机的上方&#xff0c;压缩、弯曲试验空间位于主机下横梁和工作台之间。测力仪表采用高清液晶显示屏&#xff0c;实验数据方便直观。 二、 传动系统 下横梁升降采用电机经减速器、链传动机构、丝杠副传动…

茅台葡萄酒打出节日新式营销“组合拳”,两月内落地品鉴会超千桌

执笔 | 尼 奥 编辑 | 古利特 2024年1-3月酒类进出口数据显示&#xff0c;葡萄酒进口量微增3.66%&#xff0c;进口额同比下滑11%&#xff0c;一季度整体跌势大缓&#xff0c;逐步走出普遍低迷的行情。与之相反的是&#xff0c;作为国产葡萄酒代表的茅台葡萄酒继续保持向上的战…

1288 HV5机器断电重启后无法开机

有4台服务器在增配内存和硬盘后上电无法开机&#xff0c;出现黄灯告警&#xff0c;状态码888&#xff0c;管理网不通 开始一直认为是增配的内存条的插法有问题&#xff0c;调整内存条顺序后还是一样的故障 查找资料发现ibmc有问题&#xff0c;需要升级固件&#xff0c;否则得更…

【driver5】调用堆栈函数,printk,动态打印,ftrace,proc,sysfs

文章目录 1.内核函数调用堆栈&#xff1a;4个函数2.printk&#xff1a;cat /proc/cmdline查看consolettyS03.动态打印&#xff1a;printk是全局的且只能设打印等级&#xff0c;动态打印可控制选择模块的打印&#xff0c;在内核配置打开CONFIG_DYNAMIC_DEBUG4.ftrace&#xff1a…

【统计推断】-01 抽样原理之(三)

文章目录 一、说明二、抽样分布三 均值抽样分布3.1 有限母体无放回抽样3.2 有限母体有放回抽样3.3 无限母体 四、比例抽样分布五、和差抽样分布 一、说明 上文中叙述母体和抽样的设计&#xff1b;以及抽样分布的概念&#xff0c;本篇将这种关系定量化&#xff0c;专门针对抽样的…

Day05-JavaWeb开发-请求响应(postman工具/参数/案例)分层解耦(三层架构/IOC-DI引入)

1. 请求响应 1.1 概述 1.2 请求-postman工具 1.3 请求-简单参数&实体参数 1.3.1 简单参数 1.3.2 实体参数 1.4 请求-数组集合参数 1.5 请求-日期参数&json参数 1.6 请求-路径参数 1.7 响应-ResponseBody 1.8 响应-案例 2. 分层解耦 2.1 三层架构 2.2 分层解耦(IOC-D…

QLora 里的4-bit NormalFloat Quantization中的分位数量化

目录 正态分布的分位数函数详解 1. 正态分布简介 2. 分位数函数定义 3. 正态分布的分位数函数计算 4-bit NormalFloat Quantization 4-bit NormalFloat Quantization详解 1. 4-bit NormalFloat Quantization的定义和应用 2. 4-bit NormalFloat Quantization的工作原理 …

Linux字符设备驱动(一) - 框架

字符设备是Linux三大设备之一(另外两种是块设备&#xff0c;网络设备)&#xff0c;字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备&#xff0c;常见的字符设备包括鼠标、键盘、显示器、串口等等&#xff0c;当我们执行ls -l /dev的时候&#xff0c;就能看到大量…