P2085 最小函数值 [堆]

原题传送门

思路:堆
对于 n n n个函数且 F i ( x ) = A i x 2 + B i x + C i ( x ∈ N ∗ ) F_i(x)=A_ix^2+B_ix+C_i (x\in N*) Fi(x)=Aix2+Bix+Ci(xN) 来说,我们要求这 n n n个函数的前 m m m个函数值,并由小到大依次输出,我们很自然就可以想到用堆来存放函数值
最朴素的想法就是分别把这 n n n个函数,每个函数的前 m m m个值都放进一个小根堆中,那个对于这 n m nm nm个值来说,前 m m m个值就是符合要求的值,但很不幸会 T L E TLE TLE
进一步想,由于 x , A i , B i , C i ∈ N ∗ x,A_i,B_i,C_i\in N* x,Ai,Bi,CiN,所以显而易见的是函数都是递增的,那么我们可以用一个大根堆 q q q,先将第一个函数的前 m m m个值都放入堆中,然后对接下来的每个函数的前 m m m个取值,如果函数值小于堆顶,就压入堆中,并将堆顶弹出,一旦函数值大于堆顶,由于函数递增,可以直接跳出这个循环,省略剩下明显不可能的值,达到优化的目的,最后将这 m m m个值放入数组,倒序输出即可

AC代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
typedef long long ll;
int n,m;
priority_queue<int>q;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		int A,B,C;
		scanf("%d%d%d",&A,&B,&C);
		for(int j=1;j<=m;j++){
			int k=A*j*j+B*j+C;
			if(i==1) q.push(k);
			else{
				if(k<q.top()){
					q.push(k);
					q.pop();
				}
				else break;
			}
		}
	}
	int ans[N];
	for(int i=1;i<=m;i++){
		ans[i]=q.top();
		q.pop();
	}
	for(int i=m;i>=1;i--){
		printf("%d ",ans[i]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学不会数据库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值