洛谷P2085 最小函数值(minval)
P2085 最小函数值(minval)
- 218通过
- 487提交
- 题目提供者该用户不存在
- 标签堆高级数据结构
- 难度普及+/提高
提交该题 讨论 题解 记录
最新讨论
- 暂时没有讨论
题目描述
有n个函数,分别为F1,F2,...,Fn。定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*)。给定这些Ai、Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个)。
输入输出格式
输入格式:
输入数据:第一行输入两个正整数n和m。以下n行每行三个正整数,其中第i行的三个数分别位Ai、Bi和Ci。Ai<=10,Bi<=100,Ci<=10 000。
输出格式:
输出数据:输出将这n个函数所有可以生成的函数值排序后的前m个元素。这m个数应该输出到一行,用空格隔开。
输入输出样例
输入样例#1:
3 10
4 5 3
3 4 5
1 7 1
输出样例#1:
9 12 12 19 25 29 31 44 45 54
说明
数据规模:n,m<=10000
分析:这是一道有关二次函数的题目,如果没有相关的概念,请去看初三数学课本!首先a,b,c都是正整数,那么可以知道对称轴都在y轴左边,然后x又是正整数,在对称轴右边的函数值都是单调递增的,所以当x取1的时候,有最小函数值.
因为x是正整数,当一个点被处理完后,x+=1.加入到优先队列中,为什么要用优先队列呢?很简单,因为每次都要取最小值,根据我的理解,如果一个题目需要很多次排序,那么应该就是使用优先队列.可以保证答案最优.
#include <cstdio> #include <queue> #include <cmath> #include <vector> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 100010; priority_queue < pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q; //让优先队列从小到大弹出 int n, m,x[maxn]; struct node { int a, b, c; }f[maxn]; int jisuan(int i, int x) { return x * x * f[i].a + x * f[i].b + f[i].c; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d%d%d", &f[i].a, &f[i].b, &f[i].c); for (int i = 1; i <= n; i++) x[i] = 1; for (int i = 1; i <= n; i++) { int temp = jisuan(i, 1); q.push(pair<int,int>(temp,i)); } for (int i = 1; i <= m; i++) { pair<int,int> temp = q.top(); q.pop(); int nextx = temp.second; printf("%d ", temp.first); x[nextx]++; q.push(pair<int, int>(jisuan(nextx, x[nextx]), nextx)); } return 0; }