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

news2024/10/6 12:22:30

有障碍物的不同路径数量

实验目的

(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)
{
    // 如果在大厦内 返回false
    for (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.coloradmin.cn/o/1890649.html

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

相关文章

汇聚荣拼多多电商哪些热词比较受关注?

汇聚荣拼多多电商哪些热词比较受关注?在探讨拼多多电商平台的热点关键词时&#xff0c;我们首先得明确&#xff0c;这个平台因其独特的商业模式和市场定位&#xff0c;吸引了大量消费者的目光。拼多多通过“拼团”购物的方式迅速崛起&#xff0c;成为电商行业的一个重要力量。…

5% 消耗,6 倍性能:揭秘新一代 iLogtail SPL 日志处理引擎与 Logstash 的 PK

作者&#xff1a;阿柄 引言 在当今数据驱动的时代&#xff0c;日志收集和处理工具对于保障系统稳定性和优化运维效率至关重要。随着企业数据量的不断增加和系统架构的日益复杂&#xff0c;传统日志处理工具面临着性能、灵活性和易用性等多方面的挑战。Logstash 作为一款广受欢…

qt6 通过http查询天气的实现

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

GoLand 2024 for Mac GO语言集成开发工具环境

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff08;适合自己的M芯片版或Intel芯片版&#xff09;&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功3、打开访达&#xff0c;点击【文…

Flask 数据创建时出错

当我们在使用 Flask 创建数据时遇到错误&#xff0c;可能有多种原因&#xff0c;包括代码错误、数据库配置问题或依赖项错误。具体情况我会总结成一篇文章记录下&#xff0c;主要是归类总结一些常见的解决方法和调试步骤&#xff0c;帮助大家解决问题&#xff1a; 1、问题背景 …

013、MongoDB常用操作命令与高级特性深度解析

目录 MongoDB常用操作命令与高级特性深度解析 1. 数据库操作的深入探讨 1.1 数据库管理 1.1.1 数据库统计信息 1.1.2 数据库修复 1.1.3 数据库用户管理 1.2 数据库事务 2. 集合操作的高级特性 2.1 固定集合(Capped Collections) 2.2 集合验证(Schema Validation) 2.…

如何批量创建、提取和重命名文件夹!!!

你是否还在一个一个手动创建文件名&#xff01; 你是否还在一个一个手动提取文件名&#xff01; 你是否还在一个一个手动修改文件名&#xff01; 请随小生一起批量自动创建、提取、重命名&#xff01; 1、批量创建文件夹 【案例】创建1日-31日共31个文件夹 【第一步】在A列…

VirtualBox Ubuntu Sever配置双网卡

Ubuntu 版本&#xff1a;Ubuntu Server 2404 vitrualBox 网卡配置&#xff1a; 如上配置后&#xff0c;ifconfig 只能看到 网卡1 应用了。要应用 网卡2 需要更改文件 /etc/netplan/50-cloud-init.yaml&#xff08;不同的ubuntu版本这个文件名可能不同&#xff09; 首先 ifcon…

如何在Linux上删除Systemd服务

Systemd是Linux 操作系统的系统和服务管理器&#xff0c;提供控制系统启动时启动哪些服务的标准流程。 有时&#xff0c;您可能出于各种原因需要删除systemd服务&#xff0c;例如不再需要、与其他服务冲突&#xff0c;或者您只是想清理系统。 Systemd使用单元文件来管理服务&…

OBD诊断(ISO15031) 04服务

文章目录 功能简介ISO 9141-2、ISO 14230-4和SAE J1850的诊断服务定义1、清除/重置与排放相关的诊断信息请求消息定义2、请求与排放相关的DTC响应消息定义3、报文示例 ISO 15765-4的诊断服务定义1、请求与排放相关的DTC请求消息定义2、请求与排放相关的DTC响应消息定义3、否定响…

深入详解RocketMQ源码安装与调试

1.源码下载 http://rocketmq.apache.org/dowloading/releases/ 2. 环境要求 64位系统JDK1.8(64位)Maven 3.2.x

keil5模拟 仿真 报错没有读写权限

debug*** error 65: access violation at 0x4002100C : no write permission 修改为&#xff1a; Dialog DLL默认是DCM3.DLL Parameter默认是-pCM3 应改为 Dialog DLL默认是DARMSTM.DLL Parameter默认是-pSTM32F103VE

计算机网络——数据链路层(点对点协议PPP)

点对点协议PPP的概述 对于点对点的链路&#xff0c;目前使用得最广泛的数据链路层协议是点对点协议 PPP (Point-to-Point Protocol)。 它主要应用于两个场景&#xff1a; 用户计算机与ISP之间的链路层协议就是点对点协议 PPP&#xff0c;1999年公布了回以在以太网上运行的PPP协…

配音软件有哪些?分享五款超级好用的配音软件

随着嫦娥六号的壮丽回归&#xff0c;举国上下都沉浸在这份自豪与激动之中。 在这样一个历史性的时刻&#xff0c;我们何不用声音记录下这份情感&#xff0c;让这份记忆以声音的形式流传&#xff1f; 无论是制作视频分享这份喜悦&#xff0c;还是创作音频讲述探月故事&#xff…

AI 会淘汰程序员吗?

前言 前些日子看过一篇文章&#xff0c;说国外一位拥有 19 年编码经验、会 100% 手写代码的程序员被企业解雇了&#xff0c;因为他的竞争对手&#xff0c;一位仅有 4 年经验、却善于使用 Copilot、GPT-4 的后辈&#xff0c;生产力比他更高&#xff0c;成本比他更低&#xff0c…

【分布式系统】监控平台Zabbix对接grafana

以前两篇博客为基础 【分布式系统】监控平台Zabbix介绍与部署&#xff08;命令截图版&#xff09;-CSDN博客 【分布式系统】监控平台Zabbix自定义模版配置-CSDN博客 一.安装grafana并启动 添加一台服务器192.168.80.104 初始化操作 systemctl disable --now firewalld set…

<电力行业> - 《第16课:电力领域(二)》

3 制造 3.1 电气制造厂 发电厂发电需要发电机&#xff0c;变电站升压降压需要变压器&#xff0c;输电线路输送电能需要电缆&#xff0c;这些主要电气设备的制造商&#xff0c;就是电力设备厂家。 电气设备制造是电力领域市场最基础也是最开放的领域&#xff0c;电力行业内最…

BugKu-WEB-sodirty

目录 前言 正文 信息收集 代码审计 验证 结尾 前言 七月始,暑假副本也正式开启 正文 信息收集 看着貌似没啥意义 看样子是有备份文件 下载下来 快速审计一下 代码审计 来吧 app.js没啥东西,主要是功能是实现error 我们找一找有没有index.js 找到了 \www\routes\in…

ESP32-VScode环境设置

目录 前言 一、安装VSCode 二、安装ESP32环境 1.安装ESP-IDF 2.ESP-IDF设置 3:开始配置环境 4.打开example进行验证 5.烧录 6.调整波特率 总结 前言 环境&#xff1a;Visual Studio Code 芯片&#xff1a;ESP32 说实话&#xff0c;这是我装的时间最长的一个环境&…

【数据分享】《中国金融年鉴》1986-2020年PDF版

而今天要免费分享的数据就是1986-2020年间出版的《中国金融年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 《中国金融年鉴》自1986年起&#xff0c;逐年记录着中国金融领域的发展历程、政策变化和市场动态。这部年鉴不仅是金融专业…