动态规划数字三角形模型——AcWing 275. 传纸条

动态规划数字三角形模型

定义

动态规划数字三角形模型是在一个三角形的数阵中,通过一定规则找到从顶部到底部的最优路径或最优值。

运用情况

通常用于解决具有递推关系、需要在不同路径中做出选择以达到最优结果的问题。比如计算最短路径、最大和等。

计算其他类型的最优值。比如,要求找到从顶部到底部路径上数字乘积最大,或者找到具有某种特定属性(如奇数个数最多等)的最优路径。

注意事项

  • 状态定义的准确性:要仔细分析问题,选择最能简洁且准确反映问题本质的状态表示。如果定义不当,可能导致后续递推关系复杂或无法正确求解。
  • 边界条件的多样性:不同问题的边界条件可能不同,比如三角形顶部的状态初始化,或者边缘位置的特殊处理等。
  • 递推关系的严谨性:需要充分考虑各种可能情况,确保递推关系涵盖了所有可能的决策和状态转移。

解题思路

  • 在确定状态时,有时可能需要结合一些额外的信息,比如记录路径本身或其他相关属性。
  • 递推关系的建立可能需要综合考虑多个因素,甚至可能引入辅助数组或变量来辅助计算。
  • 对于复杂的数字三角形问题,可能需要分阶段或分层进行递推计算,逐步逼近最终的最优解。

例如,在一个更复杂的数字三角形中,除了数字本身,每个位置还有一个权重,要求在权重限制下找到最大和。这时状态可能需要扩展为 dp[i][j][k] 表示到达第 i 行第 j 列且当前权重为 k 时的最大和,递推关系也会相应变得更加复杂。通过这样的细致分析和设计,可以更好地运用动态规划数字三角形模型解决各种实际问题。

AcWing 275. 传纸条

题目描述

275. 传纸条 - AcWing题库

运行代码

#include <iostream>
#include <cstring>
using namespace std;
int w[60][60], f[60*60][60][60];
void run()
{
    int n, m;
    cin >> n >> m;
    int a, b, c;
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= m; j ++)
            cin >> w[i][j];
    for(int k = 2; k <= n + m; k ++)
        for(int i1 = max(1, k - m); i1 <= n && i1 < k; i1 ++)
            for(int i2 = max(1, k - m); i2 <= n && i2 < k; i2 ++)
            {
                int j1 = k - i1, j2 = k - i2;
                if(j1 >= 1 && j1 <= m && j2 >= 1 && j2 <= m)
                {
                    int t = w[i1][j1];
                    if(i1 != i2) t += w[i2][j2];
                    int &x = f[k][i1][i2];
                    x = max(x, f[k - 1][i1][i2] + t);
                    x = max(x, f[k - 1][i1 - 1][i2] + t);
                    x = max(x, f[k - 1][i1][i2 - 1] + t);
                    x = max(x, f[k - 1][i1 - 1][i2 - 1] + t);
                }
            }
    cout << f[n + m][n][n] << endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    run();
    return 0;
}

代码思路

  • 定义了二维数组 w 来存储每个位置的好感度值。
  • f[k][i1][i2] 这个三维数组用于记录在特定阶段(即走了 k 步时),从左上角到点 (i1, j1) 和从左上角到点 (i2, j2) (其中 j1 = k - i1j2 = k - i2)两条路径所能获得的最大好感度和。
  • 通过三重循环遍历不同的位置和阶段。对于每个阶段 k 和对应的两个位置 i1i2,计算当前状态下能获得的好感度值,并与之前的状态进行比较更新。具体更新时,考虑从四个可能的方向(上一步是 i1 不变 i2 不变、i1 减 1 i2 不变、i1 不变 i2 减 1、i1 减 1 i2 也减 1)转移过来的情况,取最大值进行更新。
  • 最后输出 f[n + m][n][n],即走完整个矩阵从左上角到右下角且两条路径都到达右下角时的最大好感度和。

改进思路

  • 可以考虑添加一些必要的注释提高代码的可读性。
  • 对于一些重复的代码逻辑,可以考虑提取成函数来提高代码的简洁性和可维护性。

改进代码

#include <iostream>
#include <cstring>
using namespace std;
int w[60][60], f[60*60][60][60];
void updateMax(int k, int i1, int i2, int j1, int j2, int t) {
    int& x = f[k][i1][i2];
    x = max(x, f[k - 1][i1][i2] + t);
    x = max(x, f[k - 1][i1 - 1][i2] + t);
    x = max(x, f[k - 1][i1][i2 - 1] + t);
    x = max(x, f[k - 1][i1 - 1][i2 - 1] + t);
}
void run() {
    int n, m;
    cin >> n >> m;
    int a, b, c;
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= m; j ++)
            cin >> w[i][j];
    for(int k = 2; k <= n + m; k ++) {
        for(int i1 = max(1, k - m); i1 <= n && i1 < k; i1 ++) {
            for(int i2 = max(1, k - m); i2 <= n && i2 < k; i2 ++) {
                int j1 = k - i1, j2 = k - i2;
                if(j1 >= 1 && j1 <= m && j2 >= 1 && j2 <= m) {
                    int t = w[i1][j1];
                    if(i1!= i2) t += w[i2][j2];
                    updateMax(k, i1, i2, j1, j2, t);
                }
            }
        }
    }
    cout << f[n + m][n][n] << endl;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    run();
    return 0;
}

其它代码

#include <iostream>

using namespace std;

const int N = 60;

int n, m;
int a[N][N];
int f[N * 2][N][N];

int main()
{
    cin >> n >> m;
    
    for(int i = 1; i <= n; i ++ )
        for(int j = 1; j <= m; j ++ )
            cin >> a[i][j];
    
    for(int k = 2; k <= n + m; k ++ )
        for(int x1 = 1; x1 <= n; x1 ++ )
            for(int x2 = 1; x2 <= n; x2 ++ )
            {
                int y1 = k - x1, y2 = k - x2;
                int t = a[x1][y1];
                if(y1 >= 1 && y1 <= m && y2 >= 1 && y2 <= m)
                {
                    if(x1 != x2 || k == 2 || k == n + m)
                    {
                        t += a[x2][y2];
                        int &c = f[k][x1][x2];
                        c = max(c, f[k - 1][x1][x2] + t);
                        c = max(c, f[k - 1][x1 - 1][x2] + t);
                        c = max(c, f[k - 1][x1][x2 - 1] + t);
                        c = max(c, f[k - 1][x1 - 1][x2 - 1] + t);
                    }
                }
            }
    
    cout << f[n + m][n][n] << endl;
    
    return 0;
}

代码思路

  • 定义了常量 N 表示矩阵的最大规模。
  • 输入矩阵的行数 n 和列数 m,并读取矩阵元素值到 a 数组。
  • f[k][x1][x2] 这个三维数组用于记录某种状态下的最优值。
  • 通过三重循环遍历不同的阶段(由 k 表示)以及两个位置 x1 和 x2。根据当前的行坐标计算出对应的列坐标 y1 和 y2
  • 只有当两个位置对应的列坐标都在合法范围内时,进行计算。如果满足特定条件(比如两个位置不同或者是边界情况),计算当前的好感度值 t(包含两个位置的元素值),然后更新 f[k][x1][x2] 的值,通过与之前阶段的各种可能情况的最优值进行比较取最大值。
  • 最后输出最终状态下 f[n+m][n][n] 的值。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

中国高分辨率土壤侵蚀因子K

土壤可蚀性因子&#xff08;K&#xff09;数据&#xff0c;基于多种土壤属性数据计算&#xff0c;所用数据包括土壤黏粒含量&#xff08;%&#xff09;、粉粒含量&#xff08;%&#xff09;、砂粒含量&#xff08;%&#xff09;、土壤有机碳含量&#xff08;g/kg&#xff09;、…

【新版本来袭】ONLYOFFICE桌面编辑器8.1 —— 重塑办公效率与体验

文章目录 一、功能完善的PDF编辑器&#xff1a;重塑文档处理体验编辑文本插入和修改各种对象&#xff0c;如表格、形状、文本框、图像、艺术字、超链接、方程式等添加、旋转和删除页面添加文本注释和标注 二、幻灯片版式设计&#xff1a;创意展示的无限舞台三、改进从右至左显示…

规则引擎-Aviator 表达式校验是否成立

目录 介绍特性使用更多文献支持 介绍 Aviator是一个轻量级、高性能的Java表达式执行引擎&#xff0c;它动态地将表达式编译成字节码并运行。 特性 支持绝大多数运算操作符&#xff0c;包括算术操作符、关系运算符、逻辑操作符、位运算符、正则匹配操作符(~)、三元表达式(?:…

接口防篡改+防重放攻击

接口防止重放攻击&#xff1a;重放攻击是指攻击者截获了一次有效请求(如交易请求),并在之后的时间里多次发送相同的请求&#xff0c;从而达到欺骗系统的目的。为了防止重放攻击&#xff0c;通常需要在系统中引入一种机制&#xff0c;使得每个请求都有一个唯一的标识符(如时间戳…

Go 如何使用指针灵活操作内存

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

华为的开发语言有2中,分别是ArkTS和仓颉,他们的区别是什么?

华为的开发语言有2中&#xff0c;分别是ArkTS和仓颉&#xff0c;他们的区别在哪呢&#xff1f; ArkTS和仓颉&#xff08;cangjie&#xff09;他们的区别是什么&#xff1f; 华为的仓颉和 ArkTS 是两种不同的编程语言&#xff0c;它们有以下区别&#xff1a; 设计目的&#xff1…

emoji控必备:制作一个emoji面板插件

说在前面 &#x1f4bb;在数字时代&#xff0c;emoji表情符号已成为很多人沟通的重要工具&#xff0c;但是输入法中的emoji表情包可能不太够用&#xff0c;所以很多时候我会到在线的网站去复制emoji&#xff0c;然后再回来粘贴&#xff0c;这样操作感觉有点繁琐&#xff0c;所以…

在线朋友圈系统(Java Web)

本项目是一个基于Java Web技术栈开发的在线朋友圈系统&#xff0c;提供用户注册、登录、动态发布与评论、好友发现与管理等功能。通过Spring Boot、MySQL、MyBatis、Sa-token以及LayUI等技术实现&#xff0c;确保系统具有良好的性能和扩展性。 技术栈 后端技术 Spring Boot: …

问题-python-爬虫无法爬取外网资源问题(python爬虫)

方法一&#xff1a; 这个报错通过关掉梯子就能解决&#xff0c;目前不清楚具体原理。 后续了解具体原理了&#xff0c;我会在这篇文章上更新具体分析—— 方法二&#xff1a; 也可以把这个东西打开&#xff0c;但是用完建议关掉。

红酒品鉴新手速成:一键解锁味觉密码,让你秒变品鉴达人

红酒&#xff0c;这被誉为“液体宝石”的美酒&#xff0c;承载着丰富的口感和深邃的文化。对于许多人来说&#xff0c;品鉴红酒既是一种享受&#xff0c;也是一门艺术。然而&#xff0c;对于初学者来说&#xff0c;如何开始这场美妙的味觉之旅呢&#xff1f;今天&#xff0c;就…

vite项目自定义端口号

server.port​ 类型&#xff1a; number默认值&#xff1a; 5173 指定开发服务器端口。 注意&#xff1a;如果端口已经被使用&#xff0c;Vite 会自动尝试下一个可用的端口&#xff08;5174&#xff09;&#xff0c;所以这可能不是开发服务器最终监听的实际端口。 在vite.con…

【金】02Y90-60 大数据-HivetoMysQL

1、安装 Java 程序&#xff08;jdk&#xff09; 2、添加以下JAR包 3、确认配置成自己的数据库 ....

jenkins api部署时,一直提示pending-Finished waiting

问题&#xff1a; 调用jenkins api部署时&#xff0c;一直提示pending-Finished waiting 解决方案&#xff1a; 这个问题困扰了很久&#xff0c;一直没有思路&#xff0c;后面看到调用jenkinsAPI本身会出现一段提示&#xff0c;pending in the quiet period&#xff0c;通过搜…

NAS安全存储怎样实现更精细的数据权限管控?

NAS存储&#xff0c;即网络附属存储&#xff08;Network Attached Storage&#xff09;&#xff0c;是一种专用数据存储服务器&#xff0c;其核心特点在于将数据存储设备与网络相连&#xff0c;实现集中管理数据的功能。 NAS存储具有以下明显优势&#xff0c;而被全球范围内的企…

PostgreSQL 17 Beta 1 发布!

PostgreSQL 全球开发小组宣布&#xff0c;PostgreSQL 17 的第一个测试版本现已可供下载。此版本包含 PostgreSQL 17 正式发布时将提供的所有功能的预览&#xff0c;但测试期间版本的某些细节可能会发生变化。 #PG培训#PG考试#postgresql培训#postgresql考试#postgresql认证 您…

标准立项 | 湖库沉积物微生物多样性监测规程

饮用水水源地保护是饮用水安全保障中最重要的一个环节&#xff0c;其水质状况直接关系到供水区人民群众的身体健康。我国水资源存在水质差、资源短缺、资源时间空间分布不合理等问题。而近些年由水源地污染引发的饮用水安全事件&#xff0c;给居民的生产生活造成一定程度的影响…

Linux环境下安装MySQL5.7.33(RPM方式安装)

&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;本专栏主要发表mysql实战的文章&#xff0c;文章主要包括&#xff1a; 各版本数据库的安装、备份和恢复,性能优化等内容的学习。。 &#x1f4e3; ***如果需要观看配套视频的小伙伴们&#xff0c;请…

智慧校园-实习管理系统总体概述

智慧校园实习管理系统是专为高校、企业和学生设计的一体化数字解决方案&#xff0c;它革新了传统实习管理的方式&#xff0c;通过科技手段促进了实习资源的高效对接与管理。该系统整合了实习信息发布、申请管理、过程监督、评估反馈等多个核心环节&#xff0c;构建了一个无缝连…

关于docker存储overlay2相关问题

报错如下&#xff1a; 报错原因&#xff1a;使用rm -rf 清理overlay2导致的&#xff0c;非正常清理。 正常清理命令如下&#xff1a; # 清理Docker的所有构建缓存 docker builder prune# 删除旧于24小时的所有构建缓存 docker builder prune --filter "until24h"#删…