洛谷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;
}

 

posted @ 2016-09-05 21:27  zbtrs  阅读(1269)  评论(0编辑  收藏  举报