news 2026/5/18 15:52:00

青蛙过河的动态规划方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
青蛙过河的动态规划方法

一、 问题描述

一只青蛙想要过河,河流被等分为若干个单元格,每个单元格内可能放有一块石子(也可能没有)。青蛙只能跳上石子,不能跳入水中。

给定石子的位置列表 stones(用单元格序号升序表示),需要判断青蛙能否成功过河(即能否在最后一步跳至最后一块石子上)。

约束条件:
1. 开始时,青蛙默认已站在第一块石子上
2. 第一步只能跳跃 1 个单位(从单元格 1 跳至单元格 2)
3. 如果青蛙上一步跳跃了 k 个单位,那么接下来的跳跃距离只能选择为 k-1、k 或 k+1 个单位
4. 青蛙只能向前方(终点方向)跳跃

二、解法思路

1. 状态定义

定义二维动态规划数组 `dp[i][speed]`,表示能否以 `speed` 的速度到达第 `i` 个石子。

`i`:石子的索引(0-based)
`speed`:到达第 `i` 个石子时的跳跃速度(即从上一次跳跃的距离)

2. 初始化

开始时,青蛙静止地站在 0 号石头上,因此: `dp[0][0] = 1`(表示可以以速度 0 到达起始位置)

3. 状态转移方程

对于每个石子 `i`,我们检查所有之前的石子 `j`(j < i),计算从 `j` 跳到 `i` 的速度:speed = stones[i] - stones[j]

如果能够从石子 `j` 以某种速度跳到石子 `i`,那么需要满足以下条件:
1. `speed > 0`(只能向前跳)
2. `speed ≤ j + 1`(速度不能超过 j+1,证明见后)

状态转移方程如下:
dp[i][speed] = dp[j][speed-1] || dp[j][speed] || dp[j][speed+1]

这意味着:如果从石子 `j` 出发,以 `speed-1`、`speed` 或 `speed+1` 的速度跳跃,可以到达石子 `j`,那么就可以以 `speed` 的速度到达石子 `i`。

4. 速度范围证明

为什么 `speed ≤ j + 1`?

假设青蛙从 0 号石子开始,每次跳跃速度最多增加 1。到达第 `j` 个石子时,最多进行了 `j` 次加速(从第一次跳跃开始计算),因此最大速度不会超过 `j`。那么从第 `j` 个石子起跳,最大速度不会超过 `j+1`。所以,从石子 `j` 跳到石子 `i` 的速度 `speed` 必须满足 `speed ≤ j+1`。

代码实现

cpp
class Solution {
public:
bool canCross(vector<int>& stones) {
int n = stones.size();
// dp[i][speed]: 表示能否以speed的速度,到达第i个石头
vector<vector<int>> dp(n, vector<int>(n+1, 0));
dp[0][0] = 1;

for(int i = 1; i < n; i++) {
for(int j = 0; j < i; j++) {
int speed = stones[i] - stones[j];
// 速度必须为正,且不能超过j+1
if(speed <= 0 || speed > j+1)
continue;

// 状态转移
dp[i][speed] = dp[j][speed-1] || dp[j][speed] || dp[j][speed+1];

// 如果已经到达最后一个石子,直接返回true
if(i == n-1 && dp[i][speed] == 1)
return true;
}
}

return false;
}
};

算法分析

时间复杂度
1.外层循环遍历所有石子:O(n)
2. 内层循环对于每个石子 i,遍历所有 j < i:O(n)
3. 总时间复杂度:O(n²)

空间复杂度
-dp数组大小为 n × (n+1):O(n²)

性能表现
根据测试结果:
执行用时:320 ms(击败 23.86% 的 C++ 用户)
内存消耗:226.5 MB(击败 5.04% 的 C++ 用户)

总结

青蛙过河问题是一个典型的动态规划问题,通过定义合适的状态和状态转移方程,可以有效地解决。虽然基本的动态规划解法在时间复杂度和空间复杂度上都有优化空间,但它清晰地展示了问题的解决思路。

对于这类问题,关键点在于:
1. 正确理解问题约束条件
2. 设计合适的状态表示
3. 找到正确的状态转移关系
4. 注意边界条件的处理

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 9:34:17

突破网盘限速壁垒:百度网盘直链解析技术深度解析

在数字资源日益丰富的今天&#xff0c;百度网盘已成为我们获取和分享文件的重要平台。然而&#xff0c;面对那缓慢爬行的下载进度条&#xff0c;你是否曾感到深深的无力感&#xff1f;当项目截止期限逼近&#xff0c;当重要资料急需获取&#xff0c;那令人沮丧的下载速度往往成…

作者头像 李华
网站建设 2026/5/6 15:04:49

终极指南:E-Hentai下载器如何让你轻松打包整个图库

终极指南&#xff1a;E-Hentai下载器如何让你轻松打包整个图库 【免费下载链接】E-Hentai-Downloader Download E-Hentai archive as zip file 项目地址: https://gitcode.com/gh_mirrors/eh/E-Hentai-Downloader 还在为E-Hentai图库下载烦恼吗&#xff1f;这款免费开源…

作者头像 李华
网站建设 2026/5/18 21:18:41

如何用DSub打造私人音乐云:安卓手机听歌新体验

如何用DSub打造私人音乐云&#xff1a;安卓手机听歌新体验 【免费下载链接】Subsonic Home of the DSub Android client fork 项目地址: https://gitcode.com/gh_mirrors/su/Subsonic 想随时随地聆听珍藏的音乐库&#xff1f;DSub安卓客户端帮你实现这个梦想&#xff01…

作者头像 李华
网站建设 2026/5/15 23:11:16

Java---事件处理机制

基本说明java 事件处理是采取“委派事件模型”。当事件发生时&#xff0c;产生事件的对象&#xff0c;会把此“信息”传递给“事件的监听者”处理&#xff0c;这里所说的“信息”实际上就是 java.awt.event 事件类库里某个类库里某个类所创建的对象&#xff0c;把它称为“事件的…

作者头像 李华
网站建设 2026/5/12 7:36:11

一文讲解 USRP X310

USRP X310 是一款高性能、可扩展的软件定义无线电 (SDR) 平台&#xff0c;旨在用于下一代无线通信系统的设计和部署。它的主要特点是采用了大型 FPGA 和高速主机接口&#xff0c;提供了极高的带宽和处理能力。 以下是 USRP X310 的关键参数和特性&#xff1a;核心硬件参数参数数…

作者头像 李华