西南交通大学【算法分析与设计实验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;属于比较原始但是必须的一个步骤。 由专门的测试人员从用户视角来验证软件是否满足设计要求的行为。 更适用针对深度…

uniapp 开发备忘录-防坑指南

uniapp 开发备忘录-防坑指南 npm run dev:mp-weixin 编译微信小程序报错&#xff1a; [plugin:uni:mp-using-component] Expected ‘,’ or ‘}’ after property value in JSON at position 解决方案&#xff1a;升级uniapp 到最新 alpha 版。&#xff08;2024年7月13日&am…

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;中国建筑业经历了翻天覆地的变化。从《中国建…

伺服调试三环讲解

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

基于Hadoop平台的电信客服数据的处理与分析③项目开发:搭建基于Hadoop的全分布式集群---任务7:格式化并启动Hadoop集群

任务描述 任务内容为格式化并启动Hadoop集群&#xff0c;并修复可能出现的Bug。 任务指导 Hadoop集群启动前需要在NameNode上格式化元数据&#xff0c;成功格式化后才能启动Hadoop的HDFS和YARN。 格式化启动Hadoop集群的步骤如下&#xff1a; 1. 在NameNode&#xff08;ma…

约束:对于数据的限制

主键约束 主键约束&#xff1a;唯一约束非空约束&#xff0c;该字段上的数据不能重复且不能为null 注意&#xff1a;一张表必须有且只有一个主键 添加主键约束 -- 方式一(推荐) CREATE TABLE user(username VARCHAR(32) PRIMARY KEY,password VARCHAR(32),nick_name VARCHAR(3…

Java使用分布式锁来防止缓存穿透与雪崩

步骤如下&#xff1a; 1&#xff09;选择合适的分布式锁实现&#xff1a;常见的分布式锁实现包括ZooKeeper、Redis和基于数据库等。根据具体情况选择最佳方案。 2&#xff09;获取分布式锁&#xff1a;在需要进行操作时&#xff0c;首先尝试获取分布式锁。如果成功获取到&#…

C++文件系统操作2 - 跨平台实现文件夹的创建和删除

1. 关键词2. fileutil.h3. fileutil.cpp4. filesystem_win.h5. filesystem_win.cpp6. filesystem_unix.cpp7. 源码地址 1. 关键词 C 文件系统操作 创建文件夹 创建多级目录文件夹 删除文件夹 删除文件夹下的所有文件和子目录 跨平台 2. fileutil.h #pragma once#include <…

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…

英语中‘How often’,‘How long’和‘How soon’的区分用法

Spark: 在英语中&#xff0c;“How often”&#xff0c;“How long”&#xff0c;和“How soon”都是询问时间相关事宜的常用短语&#xff0c;但它们的用法各有不同。以下是对这三个短语的详细区分和用法说明&#xff1a; 1. How often 定义&#xff1a;用于询问某事件在一定…

安装依赖时: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;代码是你的画…