西南交通大学【算法分析与设计实验5】

有障碍物的不同路径数量

实验目的

(1)理解动态规划算法的求解过程。

(2)分析动态规划算法的时间复杂度,比较动态规划算法与其他算法的效率差异。

(3)学会如何利用动态规划算法求解具体问题,了解动态规划算法的局限性。

实验任务

(1)完成实验5.3(有障碍物的不同路径数量)的各项要求。

(2)用C++语言实现该算法并进行测试。

(3)撰写实验报告,实验报告内容包括实验目的、实验任务、实验环境、实验步骤、实验结果和实验总结等部分。

实验步骤及结果

实验预习

从左下角以最短距离到达 B 点的路径数为多少?

X1 + X2

从左下角以最短距离到达 D 点的路径数为多少?

Y1 + Y2

写出采用动态规划法求解该问题的递推方程和边界条件(简要描述dp数组、数组下标和递推方程的含义)

构建三维dp数组:dp[i][j][k]

dp数组下标含义:1. i代表横坐标  2. j代表纵坐标  3. k为0或1,0代表最短路径,1代表最短路径数

dp数组含义:从起点到达坐标为(i, j)点的最短路径和最短路径数

注:dp数组中坐标不是以题目中说明的左下角为原点,而是以数组中的(0, 0)为原点,可以在代码中看到一些坐标转换部分。

递推方程:只有不在大厦里面的点才能应用递推方程,而大厦周围的点可以应用递推方程

对于dp[i][j][0]和dp[i][j][1]有三种情况:

1.(i, j)的左边的点和下面的点都不在大厦内

则递推公式为:

如果dp[i+1][j][0] == dp[i][j-1][0]

则dp[i][j][0] = dp[i+1][j][0] + 1 

dp[i][j][1] = dp[i+1][j][1] + dp[i][j-1][1]

如果dp[i+1][j][0] > dp[i][j-1][0]

则dp[i][j][0] = dp[i+1][j][0] + 1

dp[i][j][1] = dp[i+1][j][1]

如果dp[i+1][j][0] < dp[i][j-1][0]

则dp[i][j][0] = dp[i][j-1][0] + 1

dp[i][j][1] = dp[i][j-1][1]

2.(i, j)的下面的点不在大厦内

则递推公式为:

dp[i][j][0] = dp[i+1][j][0] + 1

dp[i][j][1] = dp[i+1][j][1]

3.(i, j)的左边的点不在大厦内

则递推公式为:

dp[i][j][0] = dp[i][j-1][0] + 1

dp[i][j][1] = dp[i][j-1][1]

 对于边界条件:

在最左边和最下面的坐标的最短路径是起点到此坐标的长度,最短路径数是1,即有

dp[i][0][0] = R – i ,dp[i][0][1] = 1 , i = 0…R

dp[R][j][0] = j , dp[R][j][1] = 1 , j = 0…C

从左下角以最短路径到达 C1和C2 点的路径数是多少?

C1->6

C2->35

用C/C++语言实现该算法的源代码

#include <iostream>
using namespace std;
// 此代码坐标原点以数组(0, 0)为原点
int R;  // 行数
int C;  // 列数
int n;  // 大厦数
int num = 0;  // 数据组数
int dp[101][101][2];  // dp数组 含义在报告中已说明
int edifice[101][4];  // 大厦四个角的坐标
int res[101];  // 存储每组数据的结果
// 判断坐标是否在大厦内
bool is_ok1(int i, int j)
{// 如果在大厦内 返回falsefor (int k = 0; k < n; ++k){if (i > edifice[k][0] && i < edifice[k][1] && j > edifice[k][2] && j < edifice[k][3]){return false;}}return true;
}
// 判断从(i1, j1) 到 (i2, j2) 是否合法
bool is_ok2(int i1, int j1, int i2, int j2){// 如果(i1, j1) 在大厦内if(!is_ok1(i1, j1)){return false;}// 从左边到达if(i1 == i2){for(int i = 0;i < n;++i){if(i1 > edifice[i][0] && i1 < edifice[i][1] && j2 == edifice[i][3] && j1 == edifice[i][2]){return false;}}return true;}// 从下面到达if(j1 == j2){for(int i = 0;i < n;++i){if(j1 > edifice[i][2] && i1 < edifice[i][3] && i2 == edifice[i][0] && i1 == edifice[i][1]){return false;}}return true;}return false;
}
int main(void)
{while (cin >> R >> C){// 如果为0 0 则退出if (R == 0 && C == 0){break;}cin >> n;// 读取每个大厦的坐标for (int i = 0; i < n; ++i){int x, y, z, b;cin >> x >> y >> z >> b;// 存储大厦坐标 这里有对输入坐标转换为以(0, 0)为原点的坐标edifice[i][2] = y - 1;edifice[i][3] = edifice[i][2] + b;edifice[i][1] = R - x + 1;edifice[i][0] = edifice[i][1] - z;}// 初始化dp数组for (int i = 0; i <= R; ++i){dp[i][0][0] = R - i;dp[i][0][1] = 1;}for (int j = 0; j <= C; ++j){dp[R][j][0] = j;dp[R][j][1] = 1;}// 由下到上 由左到右遍历dp数组for (int i = R - 1; i >= 0; --i){for (int j = 1; j <= C; ++j){// 如果坐标不在大厦内if (is_ok1(i, j)){// 三种情况的递推公式if (is_ok2(i + 1, j, i, j) && is_ok2(i, j - 1, i, j)){if (dp[i + 1][j][0] == dp[i][j - 1][0]){dp[i][j][0] = dp[i + 1][j][0] + 1;dp[i][j][1] = dp[i + 1][j][1] + dp[i][j - 1][1];}else if (dp[i + 1][j][0] > dp[i][j - 1][0]){dp[i][j][0] = dp[i + 1][j][0] + 1;dp[i][j][1] = dp[i + 1][j][1];}else{dp[i][j][0] = dp[i][j - 1][0] + 1;dp[i][j][1] = dp[i][j - 1][1];}}else if (is_ok2(i + 1, j, i, j)){dp[i][j][0] = dp[i + 1][j][0] + 1;dp[i][j][1] = dp[i + 1][j][1];}else{dp[i][j][0] = dp[i][j - 1][0] + 1;dp[i][j][1] = dp[i][j - 1][1];}}}}// 将结果存储对应的res数组中res[num++] = dp[0][C][1];}// 输出结果for(int i = 0;i < num;++i){cout<<res[i]<<endl;}system("pause");return 0;
}

分析上述算法的时间复杂度,给出复杂度结果

上机实验

上机调试,利用实验教程上的测试用例验证程序是否正确

与实验教程中输出结果一致,验证正确

设计新的测试用例,对程序进行进一步验证

测试用例:

2 3

1

1 2 2 1

0 0

测试用例示意图:

手动推导结果:

其中括号中第一个数代表到达此点的最短路径,第二个数代表到达此点的最短路径数。

程序运行结果:

与手动推导结果相同。

实验总结

理解了动态规划算法的求解过程,学会了分析动态规划算法的时间复杂度和比较了动态规划算法与其他算法的效率差异。学会了如何利用动态规划算法求解具体问题,了解了动态规划算法的局限性。

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

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

相关文章

git配置ssh-keygen -t rsa -c“xxxx@xxxx.com.cn出现Too many arguments.解决办法

git配置ssh-keygen -t rsa -c"xxxxxxxx.com.cn出现Too many arguments.解决办法 问题描述 配置Git公钥私钥时候输入命令ssh-keygen -t rsa -c"xxxxxxxx.com.cn出现Too many arguments. 解决办法&#xff1a; 提示输入的参数格式不正确&#xff0c;需要注意这几个地…

按是否手工执行测试的角度划分:手工测试、自动化测试

1.手工测试&#xff08;Manual testing&#xff09; 手工测试是由人一个一个的输入用例&#xff0c;然后观察结果&#xff0c;和机器测试相对应&#xff0c;属于比较原始但是必须的一个步骤。 由专门的测试人员从用户视角来验证软件是否满足设计要求的行为。 更适用针对深度…

Markdown+VSCODE实现最完美流畅写作体验

​下载VSCODE软件 安装插件 Markdown All in One &#xff1a;支持markdown的语言的&#xff1b; Markdown Preview Enhanced &#xff1a;观看写出来文档的效果&#xff1b; Paste IMage :添加图片的 Code Spell Checker检查英文单词错误&#xff1b; 基础语法 标题 #一个…

【数据分享】《中国建筑业统计年鉴》2005-2022 PDF

而今天要免费分享的数据就是2005-2022年间出版的《中国建筑业统计年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 需要2023的数据的请添加小编咨询 数据介绍 在过去的十八个年头中&#xff0c;中国建筑业经历了翻天覆地的变化。从《中国建…

伺服调试三环讲解

在伺服调试过程中,有些项目要求不高,采用伺服自整定就可以调试好伺服,但有些项目对伺服有着比较高的要求,于是需要采取手动调试伺服参数,下面就介绍一下伺服三环参数的调试的方法。 三环指:电流环、速度环、位置环 带宽关系:电流环带宽>速度环带宽>位置环带宽 三环控…

Linux中为什么etc是存放配置文件

在计算机系统中&#xff0c;/etc 是一个目录的名称&#xff0c;通常位于Unix和类Unix操作系统中&#xff0c;如Linux。这个目录用于存放系统配置文件。/etc 的命名来源于早期Unix系统中的 "etcetera"&#xff08;拉丁语 "et cetera" 的缩写&#xff0c;意为…

AI绘画Stable Diffusion超强提示词插件!一键翻译,AI帮你写提示词!

大家好&#xff0c;我是向阳。 对于AI绘画来说&#xff0c;提示词写得好坏&#xff0c;十分影响最终生成图片的结果。会写提示词的话&#xff0c;生成的图片质量就会比较高&#xff0c;不会写的话&#xff0c;结果可能就不会好。 之前大家在使用Stable Diffuison&#xff08;以…

《数据结构与算法基础 by王卓老师》学习笔记——2.5线性表的链式表示与实现1

1.链式表示 2.链表举例 3.链式存储的相关术语 4.三个讨论题

【linux/shell案例实战】解决Linux和Windows的换行符CRLF和LF问题

目录 一.什么是Linux 和 Windows 的换行符 CRLF 和 LF 二.使用Linux 中命令 dos2unix 和 unix2dos 实现CRLF 和LF的转换 三.使用 windows 中的代码编辑器实现 CRLF 和 LF 的转换&#xff08;Notepad&#xff09; 一.什么是Linux 和 Windows 的换行符 CRLF 和 LF CR是Carria…

安装依赖时:Error: pngquant failed to build, make sure that libpng-dev is installed

错误原因&#xff1a;windows系统在安装依赖时可能报错&#xff0c;没有安装libping -dev 解决方法&#xff1a; 1、前往libping -dev官网&#xff1a;LIBPNG (sourceforge.io) 2、点击首行DOWNLOAD 3、进入网站点击Download Latest Verison下载安装&#xff0c;解压压缩包即…

2024.7.3作业

1. 梳理笔记(原创) 明天继续提问 2.程序运行后的输出结果为&#xff08;1&#xff09; #include <stdio.h> #define SQR(X) X*X void main() { int a10,k2,m1; a / SQR(km)/SQR(km); printf("%d\n",a); } 结果为1

STM32——GPIO(点亮LED)

一、GPIO是什么&#xff1f; 1、GPI/O(general porpose intput output):通用输入输出端口的简称&#xff0c;通俗地说&#xff0c;就是我们所学的51单片机的IO口&#xff0c;即P0_0等。但要注意&#xff1a;并非所有的引脚都是GPIO 输出模式下可控制端口输出高低电平&#xf…

程序员的加油站,各类技术文章,可视化技术,在线源码资源,在线实用工具,数据爬虫接口持续集成更新中

先挂网址&#xff1a;https://wheart.cn 可视化大屏模板与设计&#xff0c;在线预览 上百例可视化模板 技术文章、资源下载等各类资源导航页 echart在线实用demo 各种在线工具提升开发效率 echart在线代码模板

【电商指标详解】

前言&#xff1a; &#x1f49e;&#x1f49e;大家好&#xff0c;我是书生♡&#xff0c;本篇文章主要和大家分享一下电商行业中常见指标的详解&#xff01;存在的原因和作用&#xff01;&#xff01;&#xff01;希望对大家有所帮助。 &#x1f49e;&#x1f49e;代码是你的画…

Typora导出为Word

文章目录 一、场景二、安装1、网址2、解压并验证 三、配置四、重启Typora 一、场景 在使用Typora软件编辑文档时&#xff0c;我们可能需要将其导出为Word格式文件 当然我们可以直接在菜单里进行导出操作 文件-> 导出-> Word(.docx) 如果是第一次导出word文件&#xff0…

Python特征工程 — 1.3 对数与指数变换

目录 1 对数变换 1.1 对数变换的概念 1.2 对数变换实战 2 指数变换 2.1 指数变换的概念 2.2 指数变换实战 3 Box-Cox变换 3.1 Box-Cox变换概念 3.2 Box-Cox变换实战 1 对数变换 1.1 对数变换的概念 特征对数变换和指数变换是数据预处理中的两种常用技术&#xff0c;…

中国植物志(80卷)

中国植物志&#xff0c;全书共80卷126分册&#xff0c;3700页&#xff0c;记载了我国301科3408属31142种植物学名、形态特征、生态环境、地理分布、经济用途和物候期等。是研究中国植物的重要论著&#xff08;截图仅部分&#xff09;。

使用 bend-ingest-kafka 将数据流实时导入到 Databend

作者&#xff1a;韩山杰 Databend Cloud 研发工程师 https://github.com/hantmac Databend是一个开源、高性能、低成本易于扩展的新一代云数据仓库。bend-ingest-kafka 是一个专为 Databend 设计的实时数据导入工具&#xff0c;它允许用户从 Apache Kafka 直接将数据流导入到 D…

linux系统中的各种命令的解释和帮助(含内部命令、外部命令)

目录 一、说明 二、命令详解 1、帮助命令的种类 &#xff08;1&#xff09;help用法 &#xff08;2&#xff09;--help用法 2、如何区别linux内部命令和外部命令 三、help和—help 四、man 命令 1、概述 2、语法和命令格式 &#xff08;1&#xff09;man命令的格式&…

qt6 通过http查询天气的实现

步骤如下&#xff1a; cmakelist 当中&#xff0c;增加如下配置 引入包 访问远端api 解析返回的数据 cmakelist 当中&#xff0c;增加如下配置&#xff0c;作用是引入Network库。 引入包 3、访问远端api void Form1::on_pushButton_clicked() {//根据URL(http://t.weather.…