P1392 取数(优先队列)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1392 取数(优先队列)相关的知识,希望对你有一定的参考价值。

P1392 取数(优先队列)

类似两个序列合并求前n小。

开一个优先队列 保存当前 i − 1 i-1 i1行的前 k k k小。

把队列里的数组丢到数组b里。

然后第i行排序后丢到数组a里。

问题就变成两个序列合并问题。

注意 q . t o p ( ) ≤ a [ j ] + b [ l ] q.top()\\le a[j]+b[l] q.top()a[j]+b[l] 就可以退出了。

因为两个数组都是非递减的。

第二层和第三层循环是一个调和级数: ∑ i = 1 k k i ≈ k l o g k \\sum\\limits_i=1^k\\dfracki\\approx klogk i=1kikklogk

所以复杂度是 n m l o g 2 k nmlog^2k nmlog2k

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=805,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define db double
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

priority_queue<int>q;
int a[N],b[N];
int bid,qid;
int main()
	int n,m,k;
	scanf("%d%d%d",&n,&m,&k);
	q.push(0);
	rep(i,1,n)
		rep(j,1,m) scanf("%d",&a[j]);
		sort(a+1,a+m+1);
		bid=qid=0; while(!q.empty()) b[++bid] = q.top(),q.pop();
		for(int j=1;j<=m;j++)
			for(int l=bid;l;l--)
				if(qid<k) q.push(a[j]+b[l]),qid++;
				else if(q.top()<=a[j]+b[l]) break;
				else q.pop(),q.push(a[j]+b[l]);
			
		
	
	bid = 0;
	while(!q.empty()) b[++bid] = q.top(),q.pop();
	for(int i=bid;i;i--) printf("%d ",b[i]);
	return 0;


以上是关于P1392 取数(优先队列)的主要内容,如果未能解决你的问题,请参考以下文章

P1392 取数[堆]

springboot 中使用 RabbitMQ 配置使用优先级队列

java java 优先级 队列 PriorityBlockingQueue

python 队列

在 Linux 中控制信号量队列中的出队顺序

Python的切片操作