于动态规划的启幕之章,借 C++ 笔触绘就算法新篇

注意:代码由易到难 

P1216 [IOI 1994] 数字三角形 Number Triangles

题目链接:[IOI 1994] 数字三角形 Number Triangles - 洛谷

题目描述

观察下面的数字金字塔。

写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。

在上面的样例中,从 7→3→8→7→57→3→8→7→5 的路径产生了最大权值。

输入格式

第一个行一个正整数 �r ,表示行的数目。

后面每行为这个数字金字塔特定行包含的整数。

输出格式

单独的一行,包含那个可能得到的最大的和。

输入输出样例

输入 #1

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5 

输出 #1

30

说明/提示

【数据范围】
对于 100%100% 的数据,1≤r≤1000,所有输入在 [0,100] 范围内。

思路:动态规划,由局部最优达到全局最优

本题属于动态规划中最优子问题类

代码一(dfs+记忆化数组) 注意:本代码有一个测试点超时

#include<iostream>  // 包含标准输入输出流库
#include<algorithm> // 包含算法库,用于使用 max 函数
using namespace std;int r; // 全局变量,表示三角形的行数
int arr[1001][1001]; // 用于存储数字三角形的数组,大小为 1001x1001
int memory[1001][1001] = {0}; // 用于记忆化搜索的数组,初始化为 0// 深度优先搜索(DFS)函数,用于计算从 (x, y) 到三角形底部的最大路径和
int dfs(int x, int y) {if (memory[x][y] != 0) return memory[x][y]; // 如果已经计算过 (x, y) 的结果,直接返回int mid;if (x > r || y > x) { // 如果超出三角形范围mid = 0; // 返回 0} else {// 递归计算从 (x, y) 向下和向右下两个方向的最大路径和,并加上当前节点的值mid = max(dfs(x + 1, y), dfs(x + 1, y + 1)) + arr[x][y];}memory[x][y] = mid; // 将结果存储到记忆化数组中return mid; // 返回当前节点的最大路径和
}// 主逻辑函数,读取输入并调用 DFS
void solution() {cin >> r; // 输入三角形的行数for (int i = 1; i <= r; i++) { // 逐行读取三角形的每一行for (int j = 1; j <= i; j++) { // 逐个读取当前行的每个数字cin >> arr[i][j]; // 存储到 arr 数组中}}int maxSum = dfs(1, 1); // 从三角形顶部 (1, 1) 开始计算最大路径和cout << maxSum << endl; // 输出最大路径和
}int main() {ios::sync_with_stdio(false); // 关闭同步,提高输入输出效率cin.tie(nullptr); // 解绑 cin 和 cout,进一步提高效率int T = 1; // 测试用例数量,默认为 1// cin >> T; // 如果需要多个测试用例,可以取消注释while (T--) { // 对每个测试用例调用 solution 函数solution();}return 0; // 程序结束
}

代码二(动态规划,通过) 

#include<iostream>
#include<algorithm>
using namespace std;int r; // 三角形的行数
int arr[1002][1002]; // 存储输入的数字三角形
int mid[1002][1002] = {0}; // 动态规划数组,用于存储从底部到当前点的最大路径和// 解决数字三角形问题的函数
void solution()
{cin >> r; // 输入三角形的行数for (int i = 1; i <= r; i++) // 逐行读取三角形的数据{for (int j = 1; j <= i; j++) // 每行的列数等于行号{cin >> arr[i][j]; // 输入当前元素}}// 动态规划从三角形的底部向上计算最大路径和for (int i = r; i >= 1; i--) // 从最后一行开始向上遍历{for (int j = 1; j <= i; j++) // 遍历当前行的每个元素{// 当前点的最大路径和等于当前点的值加上其下方两个点中较大的值mid[i][j] = max(mid[i + 1][j], mid[i + 1][j + 1]) + arr[i][j];}}cout << mid[1][1] << endl; // 输出从顶部到底部的最大路径和
}int main()
{ios::sync_with_stdio(false); // 关闭同步,提高输入输出效率cin.tie(nullptr); // 解绑cin和cout,进一步提高效率int T = 1; // 测试用例数量(这里固定为1)// cin >> T; // 如果需要处理多组数据,可以取消注释while (T--) // 处理每一组数据{solution(); // 调用solution函数解决问题} return 0; // 程序结束
}

代码三(动态规划+滚动数组)

#include<iostream>
#include<algorithm>
#include<cmath>
#include<iomanip>
using namespace std;
#define av(y) setprecision(y)<<fixed;int r; // 三角形的行数
int arr[1002][1002]; // 存储输入的数字三角形
int mid[1002] = {0}; // 动态规划数组,用于存储从底部到当前点的最大路径和(一维数组)// 解决数字三角形问题的函数
void solution()
{cin >> r; // 输入三角形的行数for (int i = 1; i <= r; i++) // 逐行读取三角形的数据{for (int j = 1; j <= i; j++) // 每行的列数等于行号{cin >> arr[i][j]; // 输入当前元素}}// 动态规划从三角形的底部向上计算最大路径和for (int i = r; i >= 1; i--) // 从最后一行开始向上遍历{for (int j = 1; j <= i; j++) // 遍历当前行的每个元素{// 当前点的最大路径和等于当前点的值加上其下方两个点中较大的值// 这里使用一维数组 mid 来存储中间结果mid[j] = max(mid[j], mid[j + 1]) + arr[i][j];}}cout << mid[1] << endl; // 输出从顶部到底部的最大路径和
}int main()
{ios::sync_with_stdio(false); // 关闭同步,提高输入输出效率cin.tie(nullptr); // 解绑cin和cout,进一步提高效率int T = 1; // 测试用例数量(这里固定为1)// cin >> T; // 如果需要处理多组数据,可以取消注释while (T--) // 处理每一组数据{solution(); // 调用solution函数解决问题} return 0; // 程序结束
}

 01背包问题

此视频可帮助理解01背包问题:

【自制】01背包问题算法动画讲解_哔哩哔哩_bilibili

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次

第 i 件物品的体积是 vi,价值是 wi。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

输入格式

第一行两个整数N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤1000
0<vi,wi≤1000

输入样例

4 5
1 2
2 4
3 4
4 5

输出样例:

8

思路:就是每次打算放一个东西时,首先要考虑它放不放得下,放不下的话就直接不放;放得下的话,就要看放他划算还是不放它划算

枚举模拟算法+相对位置

 

代码一(dfs+记忆化搜索) 

#include<iostream>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
using namespace std;
#define av(y) setprecision(y)<<fixed;const int N = 1010; // 定义最大物品数量和背包容量int n, m; // 物品数量和背包容量
int v[N], w[N]; // 物品的体积和价值
int mem[N][N] = {0}; // 记忆化数组,存储已计算的状态// 深度优先搜索 + 记忆化搜索
int dfs(int x, int spV)
{// 如果当前状态已经计算过,直接返回结果if (mem[x][spV]) return mem[x][spV];int sum = 0;// 如果已经考虑完所有物品,返回0if (x < 1){return 0;}// 如果当前背包容量不足以放下第x个物品,只能选择不放if (spV < v[x])  {sum = dfs(x - 1, spV); // 不放当前物品,继续考虑前一个物品}else {// 如果背包容量足够,选择放或不放第x个物品,取两者中的最大值sum = max(dfs(x - 1, spV), dfs(x - 1, spV - v[x]) + w[x]);}// 将当前状态的最优解存储到记忆化数组中mem[x][spV] = sum;return sum;
}void solution()
{cin >> n >> m; // 输入物品数量和背包容量for (int i = 1; i <= n; i++){cin >> v[i] >> w[i]; // 输入每个物品的体积和价值}int res = dfs(n, m); // 从最后一个物品开始,背包容量为mcout << res << endl; // 输出结果
}int main()
{ios::sync_with_stdio(false); // 关闭同步,提高输入输出效率cin.tie(nullptr); // 解绑cin和cout,进一步提高效率int T = 1; // 测试用例数量(这里固定为1)// cin >> T; // 如果需要处理多组数据,可以取消注释while (T--){solution(); // 调用solution函数解决问题} return 0; // 程序结束
}

下面的与上面的代码并无本质区别

#include<iostream>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
using namespace std;
#define av(y) setprecision(y)<<fixed;const int N = 1010;int n, m;
int v[N], w[N];
int mem[N][N];// 深度优先搜索 + 记忆化搜索
int dfs(int x, int spV)
{if (x > n) return 0; // 超过物品数量,返回0if (mem[x][spV] != -1) return mem[x][spV]; // 如果已经计算过,直接返回记忆化的结果int sum = 0;if (spV < v[x])  // 如果当前背包容量不足以放下第x个物品sum = dfs(x + 1, spV); // 不放第x个物品else // 否则,选择放或不放第x个物品,取最大值sum = max(dfs(x + 1, spV), dfs(x + 1, spV - v[x]) + w[x]);mem[x][spV] = sum; // 记忆化结果return sum;
}void solution()
{cin >> n >> m; // 输入物品数量和背包容量for (int i = 1; i <= n; i++){cin >> v[i] >> w[i]; // 输入每个物品的体积和价值}memset(mem, -1, sizeof(mem)); // 初始化记忆化数组为-1int res = dfs(1, m); // 从第1个物品开始,背包容量为mcout << res << endl; // 输出结果
}int main()
{ios::sync_with_stdio(false); // 关闭同步,提高输入输出效率cin.tie(nullptr); // 解绑cin和cout,进一步提高效率int T = 1; // 测试用例数量(这里固定为1)// cin >> T; // 如果需要处理多组数据,可以取消注释while (T--) // 处理每一组数据{solution(); // 调用solution函数解决问题} return 0; // 程序结束
}

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

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

相关文章

分页按钮功能

前言 在前端开发中&#xff0c;分页功能是一个常见的需求&#xff0c;特别是当需要展示大量数据时&#xff0c;它能有效提升用户体验。该文章结合运用了HTML&#xff0c;CSS&#xff0c;JS实现网页的分页按钮功能&#xff0c;并且可以选择每页显示的条数试试更新总页数及显示当…

SAP HCM 回溯分析

最近总有人问回溯问题&#xff0c;今天把12年总结的笔记在这共享下&#xff1a; 12年开这个图的时候总是不明白是什么原理&#xff0c;教程看N次&#xff0c;网上资料找一大堆&#xff0c;就是不明白原理&#xff0c;后来为搞明白逻辑&#xff0c;按照教材的数据一样做&#xf…

gitea - fatal: Authentication failed

文章目录 gitea - fatal: Authentication failed概述run_gitea_on_my_pkm.bat 笔记删除windows凭证管理器中对应的url认证凭证启动gitea服务端的命令行正常用 TortoiseGit 提交代码备注END gitea - fatal: Authentication failed 概述 本地的git归档服务端使用gitea. 原来的用…

X Window System 架构概述

X Window System 架构概述 1. X Server 与 X Client ​ 这里引入一张维基百科的图&#xff0c;在Linux系统中&#xff0c;若用户需要图形化界面&#xff0c;则可以使用X Window System&#xff0c;其使用**Client-Server**架构&#xff0c;并通过网络传输相关信息。 ​ ​ X…

Linux防火墙基础

一、Linux防火墙的状态机制 1.iptables是可以配置有状态的防火墙&#xff0c;其有状态的特点是能够指定并记住发送或者接收信息包所建立的连接状态&#xff0c;其一共有四种状态&#xff0c;分别为established invalid new related。 established:该信息包已建立连接&#x…

[论文学习]Adaptively Perturbed Mirror Descent for Learning in Games

[论文学习]Adaptively Perturbed Mirror Descent for Learning in Games 前言概述前置知识和问题约定单调博弈&#xff08;monotone game&#xff09;Nash均衡和Gap函数文章问题定义Mirror Descent 方法评价 前言 文章链接 我们称集合是紧的&#xff0c;则集合满足&#xff1…

Go学习:类型转换需注意的点 以及 类型别名

目录 1. 类型转换 2. 类型别名 1. 类型转换 在从前的学习中&#xff0c;知道布尔bool类型变量只有两种值true或false&#xff0c;C/C、Python、JAVA等编程语言中&#xff0c;如果将布尔类型bool变量转换为整型int变量&#xff0c;通常采用 “0为假&#xff0c;非0为真”的方…

使用Pygame制作“吃豆人”游戏

本篇博客展示如何使用 Python Pygame 编写一个简易版的“吃豆人&#xff08;Pac-Man&#xff09;” 风格游戏。这里我们暂且命名为 Py-Man。玩家需要控制主角在一个网格地图里移动、吃掉散布在各处的豆子&#xff0c;并躲避在地图中巡逻的幽灵。此示例可帮助你理解网格地图、角…

ubuntu磁盘扩容

ubuntu磁盘扩容 描述先在虚拟机设置里面扩容进入Ubuntu 配置使用命令行工具parted进行分区输出如下完成 描述 执行命令,查看 fs 类型是什么 lsblk -o NAME,FSTYPE,MOUNTPOINT将60G扩容到100G&#xff0c;其中有些操作我也不知道什么意思&#xff0c;反正就是成功了&#xff0…

redis底层数据结构

底层数据结构 了解下这些咱常用的数据其底层实现是啥 在提到使用哪类数据结构之前&#xff0c;先来了解下redis底层到底有多少种数据结构 1&#xff0c;sds动态字符串 概念与由来 redis是一种使用C语言编写的nosql&#xff0c;redis存储的key数据均为string结构&#xff0…

ChatGPT怎么回事?

纯属发现&#xff0c;调侃一下~ 这段时间deepseek不是特别火吗&#xff0c;尤其是它的推理功能&#xff0c;突发奇想&#xff0c;想用deepseek回答一些问题&#xff0c;回答一个问题之后就回复服务器繁忙&#xff08;估计还在被攻击吧~_~&#xff09; 然后就转向了GPT&#xf…

趣味Python100例初学者练习01

1. 1 抓交通肇事犯 一辆卡车违反交通规则&#xff0c;撞人后逃跑。现场有三人目击该事件&#xff0c;但都没有记住车号&#xff0c;只记下了车号的一些特征。甲说&#xff1a;牌照的前两位数字是相同的&#xff1b;乙说&#xff1a;牌照的后两位数字是相同的&#xff0c;但与前…

2024-我的学习成长之路

因为热爱&#xff0c;无畏山海

蓝桥杯备考:高精度算法之除法

我们除法的高精度其实也不完全是高精度&#xff0c;而是一个高精度作被除数除以一个低精度 模拟我们的小学除法 由于题目中我们的除数最大是1e9&#xff0c;当它真正是1e9的时候&#xff0c;t是有可能超过1e9的&#xff0c;所以要用long long

Maven jar 包下载失败问题处理

Maven jar 包下载失败问题处理 1.配置好国内的Maven源2.重新下载3. 其他问题 1.配置好国内的Maven源 打开⾃⼰的 Idea 检测 Maven 的配置是否正确&#xff0c;正确的配置如下图所示&#xff1a; 检查项⼀共有两个&#xff1a; 确认右边的两个勾已经选中&#xff0c;如果没有请…

【前端】ES6模块化

文章目录 1. 模块化概述1.1 什么是模块化?1.2 为什么需要模块化? 2. 有哪些模块化规范3. CommonJs3.1 导出数据3.2 导入数据3.3 扩展理解3.4 在浏览器端运行 4.ES6模块化4.1 浏览器运行4.2 在node服务端运行4.3 导出4.3.1 分别导出4.3.2 统一导出4.3.3 默认导出4.3.4 混用 4.…

强化学习笔记(5)——PPO

PPO视频课程来源 首先理解采样期望的转换 变量x在p(x)分布下&#xff0c;函数f(x)的期望 等于f(x)乘以对应出现概率p(x)的累加 经过转换后变成 x在q(x)分布下&#xff0c;f(x)*p(x)/q(x) 的期望。 起因是&#xff1a;求最大化回报的期望&#xff0c;所以对ceta求梯度 具体举例…

20-30 五子棋游戏

20-分析五子棋的实现思路_哔哩哔哩_bilibili20-分析五子棋的实现思路是一次性学会 Canvas 动画绘图&#xff08;核心精讲50个案例&#xff09;2023最新教程的第21集视频&#xff0c;该合集共计53集&#xff0c;视频收藏或关注UP主&#xff0c;及时了解更多相关视频内容。https:…

【HTML入门】Sublime Text 4与 Phpstorm

文章目录 前言一、环境基础1.Sublime Text 42.Phpstorm(1)安装(2)启动Phpstorm(3)“启动”码 二、HTML1.HTML简介(1)什么是HTML(2)HTML版本及历史(3)HTML基本结构 2.HTML简单语法(1)HTML标签语法(2)HTML常用标签(3)表格(4)特殊字符 总结 前言 在当今的软件开发领域&#xff0c…

Kubernetes学习之包管理工具(Helm)

一、基础知识 1.如果我们需要开发微服务架构的应用&#xff0c;组成应用的服务可能很多&#xff0c;使用原始的组织和管理方式就会非常臃肿和繁琐以及较难管理&#xff0c;此时我们需要一个更高层次的工具将这些配置组织起来。 2.helm架构&#xff1a; chart:一个应用的信息集合…