蓝桥杯练习题总结(三)线性dp题(摆花、数字三角形加强版)

目录

 

一、摆花

思路一:

 确定状态:

初始化:

思路二:

确定状态:

初始化:

循环遍历:

 状态转移方程:

 二、数字三角形加强版


一、摆花

题目描述

小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆。通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号。为了在门口展出更多种花,规定第i种花不能超过αi盆。摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。试编程计算,一共有多少种不同的摆花方案。

输入描述

第一行包含两个正整数n和m,中间用一个空格隔开。

第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1、a2、...、an。

其中,0 < n ≤ 100,0 < m ≤ 100,0 ≤ ai ≤ 100。

输出描述

输出只有一行,一个整数,表示有多少种方案。注意:因为方案数可能很多,请输出方案数对10^9 + 7取模的结果。

输入样例

2 4 3 2

输出样例

2

解题思路

思路一:

 确定状态:

首先,需要明确问题的要求:给定n种不同的花和每种花的最大数量限制,求出在摆放m盆花时,能够形成的不同摆花方案数。这个问题的关键在于每种花可以选择摆放的数量从0到其最大限制,且摆放的花必须按照花的种类顺序排列。

在动态规划中,定义状态是至关重要的一步。这里,我们定义状态dp[i][j]为考虑前i种花时,摆放j盆花的不同方案数。

int n, m; cin >> n >> m;
vector<int>a(n + 1);
vector<vector<int> >dp(101, vector<int>(101));

初始化:

初始化第一种花的情况,因为只有一种花,所以可以从0到a[1]朵任意选择,都只有一种方式

for (int i = 0; i <= a[1]; i++) dp[1][i] = 1;
  • 外层循环遍历花的种类:从1到n,(花的种类为0时情况已初始化)对每种花进行遍历。

  • 中层循环遍历目标花的总数:从0到m,对可能摆放的花的总数进行遍历。

  • 在内层循环中,再加一个循环遍历当前考虑的这种花可以选择的数量(从0到该种花的数量上限或剩余可摆放数量的较小值),这里通过检查j - k >= 0来确保不会有负数的情况发生。
 for (int i = 2; i <= n; i++) { // 遍历每一种花 for (int j = 0; j <= m; j++) { // 遍历当前要选的花的总数for (int k = 0; k <= a[i] && j - k >= 0; k++) {......}}}
  • 状态转移方程dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % p;的含义是,要得到前i种花中摆放j盆花的方案数,需要将所有可能包含第i种花的数量(从0到a[i])的方案数加起来。每次更新dp[i][j]时,都要对p取模,以避免整数溢出并满足题目要求。
dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % p;
#include <bits/stdc++.h>
using namespace std;
const int N = 200, p = 1e6 + 7;
int dp[N][N], n, m, a[N];int main()
{cin >> n >> m;// 输入花的种类数n和目标数mfor (int i = 1; i <= n; i++) cin >> a[i];// 输入每种花的数量for (int i = 0; i <= a[1]; i++) dp[1][i] = 1;// 初始化第一种花的情况,因为只有一种花,所以可以从0到a[1]朵任意选择,都只有一种方式// 动态规划填表过程for (int i = 2; i <= n; i++) { // 遍历每一种花 for (int j = 0; j <= m; j++) { // 遍历当前要选的花的总数for (int k = 0; k <= a[i] && j - k >= 0; k++) {// 状态转移方程:dp[i][j]表示前i种花选出j朵的方式数,它等于前i - 1种花选出j - k朵的方式数之和dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % p;}}}cout << dp[n][m];// 输出结果,即前n种花选出m朵的方式数(模p意义下)return 0;
}

思路二:

确定状态:

首先,需要明确问题的要求:给定n种不同的花和每种花的最大数量限制,求出在摆放m盆花时,能够形成的不同摆花方案数。这个问题的关键在于每种花可以选择摆放的数量从0到其最大限制,且摆放的花必须按照花的种类顺序排列。

在动态规划中,定义状态是至关重要的一步。这里,我们定义状态dp[i][j]为考虑前i种花时,摆放j盆花的不同方案数。

int n, m; cin >> n >> m;
vector<int>a(n + 1);
vector<vector<int> >dp(101, vector<int>(101));

初始化:

对于本问题,我们知道不摆放任何花(即j=0时)只有一种方案,即什么花都不摆。因此,初始化dp[0][0] = 1,表示没有花时,摆放0盆花的方案数为1。其他情况(即当j>0时),在没有考虑任何花的情况下是不可能摆放任何花的,这些状态默认为0,反映了不可能发生的情况。

dp[0][0] = 1;

循环遍历:

  • 外层循环遍历花的种类:从1到n,(花的种类为0时情况已初始化)对每种花进行遍历。

  • 中层循环遍历目标花的总数:从0到m,对可能摆放的花的总数进行遍历。

  • 内层循环遍历当前种类花的可能数量:从0到当前种类花的数量限制或j中的较小值(因为不可能摆放超过总数j的花)。这一步是优化的关键,通过只遍历到min(a[i], j)来减少不必要的计算。

for (int i = 1; i <= n; i++){for (int j = 0; j <= m; j++){for (int k = 0; k <= min(a[i],j); k++){......}}}

 状态转移方程:

dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % p;
#include <bits/stdc++.h>
using namespace std;
const int p = 1e6 + 7;int main()
{int n, m; cin >> n >> m;vector<int>a(n + 1);vector<vector<int> >dp(101, vector<int>(101));for (int i = 1; i <= n; i++){cin >> a[i];}dp[0][0] = 1;for (int i = 1; i <= n; i++){for (int j = 0; j <= m; j++){for (int k = 0; k <= min(a[i],j); k++){dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % p;}}}cout << dp[n][m] % p;
}

 二、数字三角形加强版

数字三角形最大路径和问题

给定一个数字三角形,从三角形的顶部到底部有多条不同的路径。对于每条路径,把路径上的数加起来可以得到一个和。任务是找到最大的和。

路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过1。

输入描述:

输入的第一行包含一个整数N(1≤N≤100),表示三角形的行数。下面的N行给出数字三角形。数字三角形上的数都是0至100之间的整数。

输出描述:

输出一个整数,表示最大路径和。

输入输出样例:

输入:

5

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

输出:

27

数字三角形

http://t.csdnimg.cn/2IdF4

此题与之前这题的不同点在与多了一个这样的要求:

  • 此外,向左下走的次数与向右下走的次数相差不能超过1。

意为:路径最后会停在最后一行中间的位置。此时有奇数和偶数两种情况,但是可以统一考虑为一种情况:

max(dp[n][(n + 1) / 2], dp[n][(n + 2) / 2]);

如果是奇数,那么两个数值相同;如果是偶数,取更大的一个,皆符合题意。

#include <iostream>
using namespace std;
int a[200][200], dp[200][200], n;
int main()
{cin >> n;for (int i = 1; i <= n; i++)for (int j = 1; j <= i; j++)cin >> a[i][j];dp[1][1] = a[1][1];for (int i = 2; i <= n; i++)for (int j = 1; j <= i; j++)dp[i][j] = a[i][j] + max(dp[i - 1][j], dp[i - 1][j - 1]);cout << max(dp[n][(n + 1) / 2], dp[n][(n + 2) / 2]);return 0;
}

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

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

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

相关文章

Uni-app/Vue/Js本地模糊查询,匹配所有字段includes和some方法结合使用e

天梦星服务平台 (tmxkj.top)https://tmxkj.top/#/ 1.第一步 需要一个数组数据 {"week": "全部","hOutName": null,"weekendPrice": null,"channel": "门市价","hOutId": 98,"cTime": "…

【Redis】Redis 内存管理,Redis事务,bigkey和hotkey

目录 Redis 内存管理 缓存数据设置过期时间&#xff1f; Redis 是如何判断数据是否过期的呢&#xff1f; 过期删除策略 内存淘汰机制 主从模式下对过期键的处理&#xff1f; LRU和LFU的区别 Redis事务 定义和原理 Redis 事务的注意点&#xff1f; 为什么不支持回滚&a…

SQLite数据库文件损坏的可能几种情况(一)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;十三&#xff09; 下一篇&#xff1a;SQLite使用的临时文件&#xff08;二&#xff09; 概述 SQLite数据库具有很强的抗损坏能力。如果应用程序崩溃&#xff0c…

指针数组的有趣程序【C语言】

文章目录 指针数组的有趣程序指针数组是什么&#xff1f;指针数组的魅力指针数组的应用示例&#xff1a;命令行计算器有趣的颜色打印 结语 指针数组的有趣程序 在C语言的世界里&#xff0c;指针是一种强大的工具&#xff0c;它不仅能够指向变量&#xff0c;还能指向数组&#…

HBase Shell基本操作

一、进入Hbase Shell客户端 先在Linux Shell命令行终端执行start-dfs.sh脚本启动HDFS&#xff0c;再执行start-hbase.sh脚本启动HBase。如果Linux系统已配置HBase环境变量&#xff0c;可直接在任意目录下执行hbase shell脚本命令&#xff0c;就可进入HBase Shell的命令行终端环…

Unity Mobile Notifications推送问题

1.在部分机型点击通知弹窗进不去游戏 把这里改成自己的Activity 2.推送的时候没有横幅跟icon红点 主要是第一句话 注册的时候选项可以选择 defaultNotificationChannel new AndroidNotificationChannel(“default_channel”, “Default Channel”, “For Generic notifica…

LinkedIn 互联网架构扩展简史

LinkedIn成立于 2003 年&#xff0c;其目标是连接到您的网络以获得更好的工作机会。第一周只有 2,700 名会员。时间快进了很多年&#xff0c;LinkedIn 的产品组合、会员基础和服务器负载都取得了巨大的增长。 如今&#xff0c;LinkedIn 在全球运营&#xff0c;拥有超过 3.5 亿会…

今日AI热点:科技前沿新动态

引言&#xff1a; 人工智能领域日新月异&#xff0c;每天都有令人振奋的新进展。从苹果到谷歌&#xff0c;从OpenAI到Meta&#xff0c;各大科技巨头纷纷推出创新产品和技术&#xff0c;不断推动着人工智能的发展。让我们一起来看看今日AI热点&#xff0c;探索这个充满活力和激情…

C++从入门到精通——命名空间

命名空间 前言一、命名空间引例什么是命名空间 二、命名空间定义正常的命名空间定义嵌套的命名空间多个相同名称的命名空间 三、命名空间使用加命名空间名称及作用域限定符使用using将命名空间中某个成员引入使用using namespace 命名空间名称引用引用命名空间和引用头文件有什…

Mac安装minio

Mac安装minio 本文介绍使用 mac 安装 MinIO。 所有软件安装优先参考官网&#xff1a;MinIO Object Storage for MacOS — MinIO Object Storage for MacOS #使用 brew 安装 minio brew install minio/stable/minio#找到 minio tong ~ $ brew list minio /opt/homebrew/Cella…

【ssh连接】奇奇怪怪报错记录

gitlab配置ssh连接&#xff0c;先跟着教程生成密钥&#xff0c;上传公钥&#xff0c;将服务器信息存入config文件&#xff0c;但是ssh连接超时&#xff0c;很急&#xff0c;想用服务器&#xff0c;各种搜索尝试&#xff0c;搞了两三天别的什么都没干&#xff0c;还是没解决&…

深度学习pytorch——激活函数损失函数(持续更新)

论生物神经元与神经网络中的神经元联系——为什么使用激活函数&#xff1f; 我们将生物体中的神经元与神经网络中的神经元共同分析。从下图可以看出神经网络中的神经元与生物体中的神经元有很多相似之处&#xff0c;由于只有刺激达到一定的程度人体才可以感受到刺激&#xff0c…

硬件6、AD设计PcbLib之引脚间如何设置距离及设置PCB元器件丝印

设置引脚间的距离 一个器件有两个引脚&#xff0c;在制作这个器件的pcblib时&#xff0c;需要设置两个引脚之间的距离 1、先选中其中一个引脚 2、然后拖动至两个引脚重叠 3、按下M键&#xff0c;通过X&#xff0c;Y移动选中对象 4、输入两个引脚中心点之间的距离 5、然后两…

【随笔】Git -- 基本概念和使用方式(五)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

排序C++

题目 法1 sort升序排序&#xff0c;再逆序输出 #include<iostream> #include<algorithm> using namespace std;const int N 5e53;//注意const&#xff0c;全局 int a[N]; int main() {//错误int N5e53;//错误const int a[N];int n;cin >> n;for (int i 1;…

水电站生态流量监测解决方案:亲历水电站生态监控改造

​记得那是在2022年夏天,我所在的环保咨询公司接到了一项非常具有挑战性的监测项目。某省的环保部门要求对辖区内所有水电站的生态流量情况进行评估,并给出整改建议。作为项目负责人,我深知这项工作的重要意义。&#xff08;选自&#xff1a;智慧水务数字孪生安全监测解决方案提…

正式发布:VitePress 1.0 现代化静态站点生成器!

大家好&#xff0c;我是奇兵&#xff0c;今天介绍一下现代化静态站点生成器!&#xff0c;希望能帮到大家。 3 月 21 日&#xff0c; 由 Vue 团队出品的现代化静态站点生成器 VitePress 正式发布 1.0 版本&#xff01;它专为构建快速、以内容为中心的网站而生&#xff0c;能够轻…

Wagtail-基于Python Django的内容管理系统CMS实现公网访问

目录 前言 1. 安装并运行Wagtail 1.1 创建并激活虚拟环境 2. 安装cpolar内网穿透工具 3. 实现Wagtail公网访问 4. 固定Wagtail公网地址 前言 Wagtail是一个用Python编写的开源CMS&#xff0c;建立在Django Web框架上。Wagtail 是一个基于 Django 的开源内容管理系统&…

python知识点总结(十)

python知识点总结十 1、装饰器的理解、并实现一个计时器记录执行性能&#xff0c;并且将执行结果写入日志文件中2、队列和栈的区别&#xff0c;并且用python实现3、设计实现遍历目录与子目录4、CPU处理进程最慢的情况通常发生在以下几种情况下&#xff1a;5、CPU处理线程最慢的…

计算机网络基础——网络安全/ 网络通信介质

chapter3 网络安全与管理 1. 网络安全威胁 网络安全&#xff1a;目的就是要让网络入侵者进不了网络系统&#xff0c;及时强行攻入网络&#xff0c;也拿不走信息&#xff0c;改不了数据&#xff0c;看不懂信息。 事发后能审查追踪到破坏者&#xff0c;让破坏者跑不掉。 网络…