当前位置: 首页 > news >正文

【CSP试题回顾】202209-2-何以包邮?

CSP-202209-2-何以包邮?

解题关键:计算数组所以子序列和

题目是一个典型的动态规划问题,可以翻译为:给定一个数组 a,该数组包含 n 个正整数。你需要找出所有可能的子序列的和,并将这些和保存下来。现在,给定一个数 x,你需要找出在所有可能的子序列的和中,最小的但是大于或等于 x 的那个和。如果没有和大于或等于 x,则返回 -1(题目描述中并未明确提及此情况,但这通常是类似问题的一种处理方式)。这个问题的关键在于如何有效地计算所有可能子序列的和,并快速找到满足条件的最小和

本题的解法是通过动态编程方法来计算数组的所有子序列和,假设输入数组 a = [1, 3, 2],我们将逐步说明代码如何计算所有可能子序列的和。初始时,arr = [](空数组),表示还没有计算任何子序列的和。

第一步:处理元素 1

  • 1 加入到 arrarr 变为 [1]
  • 这时,arr 包含的是数值 1 和它自身的和(因为单个元素也被视为子序列)。

第二步:处理元素 3

  • 遍历当前的 arr(只包含 1),并将 3 添加到每个元素上,得到新的子序列和为 41 + 3)。然后将新和 4 加入 arr,此时 arr = [1, 4]
  • 同时,将 3 本身也添加到 arr,因为它自己也是一个子序列,此时 arr 变为 [1, 4, 3]
  • arr 进行排序和去重(去重是为了节省空间开销,此例中不需要去重),得到 [1, 3, 4]

第三步:处理元素 2

  • 遍历当前的 arr(包含 [1, 3, 4]),并将 2 添加到每个元素上,得到新的子序列和 31 + 2)、53 + 2)、64 + 2)。将这些新和加入 arr,此时 arr = [1, 3, 4, 3, 5, 6]
  • 2 本身也添加到 arr,因为它自己也是一个子序列,此时 arr 变为 [1, 3, 4, 3, 5, 6, 2]
  • 再次对 arr 进行排序和去重,得到 [1, 2, 3, 4, 5, 6]

现在,arr 包含了数组 [1, 3, 2] 所有可能的子序列和:1(来自子序列 [1])、2(来自子序列 [2])、3(来自子序列 [1, 2][3])、4(来自子序列 [1, 3])、5(来自子序列 [2, 3])、6(来自子序列 [1, 2, 3])。通过这种方法,代码逐个处理数组中的每个元素,并动态地构建出所有可能的子序列和的集合。

解题思路

上述代码使用了C++ STL中的 set 来高效地处理和存储所有可能的子序列和。这里也采用了类似的动态规划思想,但与前一种方法相比,使用 set 的优点在于自动排序和去重

1.set介绍

set 是C++标准模板库(STL)中的一个容器,用于存储唯一元素,按照特定顺序排列。set 中的元素默认按升序排列,且所有元素都是唯一的,自动去重。set 的实现通常基于红黑树,一个自平衡的二叉搜索树,这使得其大多数操作(如插入、删除、搜索)的时间复杂度为 O(log n)

2.解题思路

  1. 变量初始化

    • 定义整数 nx,其中 n 是数组的长度,x 是我们要查找的目标值。
    • 创建一个 set 类型的变量 sums,并将 0 插入其中。在动态规划中,0 表示空子序列的和,是初始状态。
  2. 遍历数组

    • 遍历输入的每个元素 t
    • 创建一个新的 set newSums 来存储新增的子序列和。
    • 遍历 sums 中已存在的每个和,将这个和与新元素 t 相加,然后将结果添加到 newSums 中。
  3. 更新子序列和的集合

    • newSums 中的所有元素添加到 sums 中。由于 sums 是一个 set,这个操作会自动去重并保持元素的排序
  4. 查找和输出

    • 使用 sums.lower_bound(x) 查找第一个大于或等于 x 的元素。lower_bound 是一个二分查找方法,可以在对数时间内完成,最后输出找到的元素。

完整代码

#include <iostream>
#include <set>
using namespace std;int main() {int n, x;cin >> n >> x;set<int> sums;sums.insert(0);for (int i = 0; i < n; i++) {int t;cin >> t;set<int> newSums; // 创建一个新的set来存储新的和      for (auto it : sums) { // 遍历现有的和,添加新的和newSums.insert(it + t);}sums.insert(newSums.begin(), newSums.end()); // 将新的和合并到主set中}auto it = sums.lower_bound(x); // 使用lower_bound查找一个大于或等于x的值,这是一个log(n)的操作cout << *it;return 0;
}

请添加图片描述

相关文章:

  • 各中间件性能、优缺点对比
  • Android使用OpenGL和FreeType绘制文字
  • 【MATLAB】语音信号识别与处理:卷积滑动平均滤波算法去噪及谱相减算法呈现频谱
  • 第七篇:人工智能与机器学习技术VS量测(Measurement)- 我为什么要翻译介绍美国人工智能科技巨头IAB公司 - 它是如何赋能数字化营销生态的?
  • 前端工具网站合集(持续更新)
  • 数学建模介绍
  • 探索云原生世界:Serverless 技术的崛起与应用
  • Centos 9 安装 k8s
  • python基础使用之“__name__==‘__main__‘”作用
  • 大数据开发-Hadoop分布式集群搭建
  • MySQL从入门到实战
  • 使用mysqld --install命令时出现MSVCR120.dll文件丢失错误
  • 详细分析Vue中的$refs用法
  • 【Linux C | 网络编程】广播概念、UDP实现广播的C语言例子
  • 关于 Rust 的 From 特性的尝试
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • ➹使用webpack配置多页面应用(MPA)
  • Fastjson的基本使用方法大全
  • iOS | NSProxy
  • Java多线程(4):使用线程池执行定时任务
  • Node项目之评分系统(二)- 数据库设计
  • 阿里云购买磁盘后挂载
  • 关于 Cirru Editor 存储格式
  • 基于 Babel 的 npm 包最小化设置
  • 扑朔迷离的属性和特性【彻底弄清】
  • 微信小程序:实现悬浮返回和分享按钮
  • Java总结 - String - 这篇请使劲喷我
  • zabbix3.2监控linux磁盘IO
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​插件化DPI在商用WIFI中的价值
  • ​水经微图Web1.5.0版即将上线
  • #NOIP 2014#Day.2 T3 解方程
  • (2)STM32单片机上位机
  • (c语言)strcpy函数用法
  • (六)激光线扫描-三维重建
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (一)基于IDEA的JAVA基础10
  • .gitignore文件设置了忽略但不生效
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .Net 代码性能 - (1)
  • .net 托管代码与非托管代码
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .Net的C#语言取月份数值对应的MonthName值
  • .NET性能优化(文摘)
  • .NET中winform传递参数至Url并获得返回值或文件
  • .NET中的Exception处理(C#)
  • .Net转前端开发-启航篇,如何定制博客园主题
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @zabbix数据库历史与趋势数据占用优化(mysql存储查询)
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?