洛谷 P2085 最小函数值(minval)

来源:互联网 发布:病毒查杀软件 编辑:程序博客网 时间:2024/05/22 23:39

题目描述

有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

分析:
用一个优先队列q保存当前最小的m个函数值。

因为a,b,c>0,所以f(x)为增函数。所以这m个值一定在x=1,2,3…m中取得。

首先把第一个函数的前m个值压入队列中。对于第2、3、4……n个函数,每次将x遍历1到m。如果f(x)大于等于堆顶,那么x及x以后的函数值都比这m个大,可以不用计算了直接break掉。否则,弹出堆顶,将f(x)压入队列。

注意输出时倒序输出,用一个数组保存一下答案

代码:

type  see=record        t,pos,x:longint;      end; const   maxn=10000; var   a:array[1..maxn,1..3]of longint;   b:array[0..maxn]of see;   n,e,i,j:longint;function fe(p,x:longint):longint;begin  fe:=a[p,1]*x*x+a[p,2]*x+a[p,3];end;procedure down(m,k:longint);var  tt:longint;  temp:see;  f:boolean;begin  if k*2>m then exit;  f:=false;  repeat    k:=k*2;    if (k+1<=m)and(b[k+1].t<b[k].t) then k:=k+1;    if b[k].t<=b[k div 2].t then      begin        temp:=b[k div 2];        b[k div 2]:=b[k];        b[k]:=temp;      end    else f:=true;  until f or (k*2>m);end;begin   readln(n,e);   for i:=1 to n do     begin       readln(a[i,1],a[i,2],a[i,3]);       b[i].t:=fe(i,1);       b[i].pos:=i;       b[i].x:=1;     end;   for i:=n div 2 downto 1 do    down(n,i);  for i:=1 to e-1 do    begin      write(b[1].t,' ');      inc(b[1].x);      b[1].t:=fe(b[1].pos,b[1].x);      down(n,1);    end;    writeln(b[1].t);end.
0 1
原创粉丝点击