news 2026/6/8 0:47:51

最小函数值(minval)(信息学奥赛一本通- P1370)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
最小函数值(minval)(信息学奥赛一本通- P1370)

【题目描述】

有n个函数,分别为F1,F2,...,Fn。定义Fi(x)=Aix2+Bix+Ci(x∈N∗)。给定这些Ai、Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个)。

【输入】

第一行输入两个正整数n和m。

以下n行每行三个正整数,其中第i行的三个数分别位Ai、Bi和Ci。输入数据保证Ai<=10,Bi<=100,Ci<=10000。

【输出】

将这n个函数所有可以生成的函数值排序后的前m个元素。这m个数应该输出到一行,用空格隔开。

【输入样例】

3 10 4 5 3 3 4 5 1 7 1

【输出样例】

9 12 12 19 25 29 31 44 45 54

【提示】

【数据规模】

n,m≤10000。

1. 解题思路分析

本题的核心目标是从 n 个二次函数生成的无数个值中,筛选出最小的 m 个数。由于 m 远小于可能产生的数据总量,直接计算所有值并排序(O(N⋅Mlog(NM)))显然不够高效。我们采用了“维护固定大小集合”的策略。

数据结构选择:大根堆

虽然题目要求的是“最小”的数,但在维护一个容量为 m 的候选集合时,我们需要使用大根堆priority_queue默认大根堆)。

  • 理由:我们要时刻知道当前选出的 m 个数中,最大的那个数是多少(即堆顶元素)。

  • 作用:堆顶元素是当前候选集合的“门槛”。对于一个新计算出的函数值,只有当它小于堆顶时,它才有资格进入前 m 名。此时我们将堆顶弹出(淘汰当前第 m 小),将新值压入。

关键优化:利用函数单调性

题目给定 A,B,C 均为正整数,因此二次函数 f(x)=A*x^2+B*x+C 在 x≥1 的区间上是单调递增的。 这一性质对于优化算法至关重要:

  • 在遍历某一组参数 (A,B,C) 时,我们让 x 从 1 开始递增。

  • 如果当前计算出的 f(x) 已经大于或等于堆顶元素,由于函数的单调递增性,后续的 f(x+1),f(x+2)... 必然也大于堆顶。

  • 结论:此时无需继续计算该函数的后续值,直接break跳出当前循环,处理下一组函数。这一剪枝操作保证了算法不会超时。

2. 算法流程总结

  1. 初始化:读取第一组函数参数,计算前 m 个值推入优先队列,建立初始的“最小m数”集合。

  2. 动态更新

    • 依次读取后续 n−1 组函数参数。

    • 对于每组函数,从 x=1 开始计算。

    • 若 f(x)<q.top():说明找到了更优解,执行pop()push(f(x))

    • 若 f(x)≥q.top():触发单调性剪枝,直接break

  3. 结果输出:由于大根堆弹出顺序是从大到小,需要将元素暂存入数组,最后倒序输出以满足题目从小到大的要求。

3. 实现细节与注意事项

  • 数据范围由于涉及到 x^2 的运算,函数值可能会超过int范围,因此优先队列和中间变量必须使用long long

  • 输出数组类型:代码中用于倒序输出的数组h应定义为long long以匹配优先队列的数据类型。

  • 时间复杂度:在最坏情况下(剪枝未频繁触发),每次堆操作为 O(logm)。由于单调性的存在,实际交换次数远小于理论上限,整体效率足以通过测试点。

//思路:先通过第一组abc算出x(1-m)的m个f值存入优先队列(最大堆),后面每一组都通过与堆顶 //进行比较,如果小于堆顶就存进去,直到大于堆顶就开始下一组,最后堆里存放的一定是最小的m个数,输出即可 #include <iostream> #include <queue> using namespace std; int a,b,c; priority_queue<long long> q;//最大堆 long long f(int x,int a,int b,int c){ return a*x*x+b*x+c; } int main(){ int n,m; cin>>n>>m; //第一组数据先存入优先队列 cin>>a>>b>>c; for(int i=1;i<=m;i++){ long long tmp=f(i,a,b,c); q.push(tmp); } for(int i=2;i<=n;i++){//从第二组开始比较 cin>>a>>b>>c; for(int j=1;j<=m;j++){ long long tmp=f(j,a,b,c); if(tmp<q.top()){//tmp比堆里的最大值要小,就弹出堆顶,然后存入tmp q.pop(); q.push(tmp); } else{//i组当前j的情况下tmp已经大于堆顶(即堆里的最大值),就不需要让j继续增加了,可以比较下一组了 break; } } } //因为要从小到大输出,那就把堆先存进一个数组再输出 long long h[10001]; int cnt=0;//存进多少个数; while(!q.empty()){ h[++cnt]=q.top(); q.pop(); } for(int i=cnt;i>=1;i--) cout<<h[i]<<" "; return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 16:21:44

企业级扶贫助农系统管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】

摘要 背景相关&#xff1a; 随着乡村振兴战略的深入推进&#xff0c;数字化技术在扶贫助农领域的应用日益广泛。传统扶贫模式存在信息不对称、资源分配不均、管理效率低下等问题&#xff0c;亟需通过信息化手段提升扶贫工作的精准性和可持续性。企业级扶贫助农系统通过整合互联…

作者头像 李华
网站建设 2026/6/7 22:42:02

信息管理毕设2026开题汇总

1 引言 毕业设计是大家学习生涯的最重要的里程碑&#xff0c;它不仅是对四年所学知识的综合运用&#xff0c;更是展示个人技术能力和创新思维的重要过程。选择一个合适的毕业设计题目至关重要&#xff0c;它应该既能体现你的专业能力&#xff0c;又能满足实际应用需求&#xff…

作者头像 李华
网站建设 2026/6/7 16:57:47

LangFlow权限控制系统设想与路线图

LangFlow权限控制系统设想与路线图 在AI应用开发日益普及的今天&#xff0c;LangChain已经成为连接大语言模型与外部系统的核心桥梁。然而&#xff0c;随着团队协作和企业级部署需求的增长&#xff0c;基于LangChain构建的可视化工具LangFlow也面临着新的挑战——如何在保持低代…

作者头像 李华
网站建设 2026/6/7 3:07:54

LangFlow医疗辅助诊断系统搭建全过程

LangFlow医疗辅助诊断系统搭建全过程 在智慧医疗的浪潮中&#xff0c;一个现实问题始终困扰着医院信息化团队&#xff1a;如何让医生真正参与到AI系统的构建中&#xff1f;传统的智能辅助诊断系统往往由工程师闭门开发&#xff0c;临床专家只能被动接受输出结果。即便模型准确率…

作者头像 李华
网站建设 2026/6/8 11:13:22

LangFlow图像生成任务整合Stable Diffusion步骤

LangFlow整合Stable Diffusion实现图像生成的完整实践 在AI应用开发日益复杂的今天&#xff0c;如何快速构建一个从自然语言输入到高质量图像输出的端到端系统&#xff0c;成为许多开发者和创意工作者关注的核心问题。传统的做法是编写大量胶水代码来串联大模型调用、提示词优化…

作者头像 李华
网站建设 2026/6/8 8:56:17

GESP认证C++编程真题解析 | B3927 [GESP202312 四级] 小杨的字典

​欢迎大家订阅我的专栏&#xff1a;算法题解&#xff1a;C与Python实现&#xff01; 本专栏旨在帮助大家从基础到进阶 &#xff0c;逐步提升编程能力&#xff0c;助力信息学竞赛备战&#xff01; 专栏特色 1.经典算法练习&#xff1a;根据信息学竞赛大纲&#xff0c;精心挑选…

作者头像 李华