優先隊列實踐和優勢(相對於sort函數)

總結:

當某一數組需要動態插入單個元素或者多個並排序且要選用最大值時使用優先隊列

教訓:

如果選用sort函數每次都重新排序時間複雜度過高,即使是自己寫一個for循環時間複雜度也是o(n),但是使用優先隊列則可以降低到o(logn)且自動排序。

例題:

在這裏插入圖片描述

超時代碼

#include<iostream>
#include<algorithm>
using namespace std;
struct node{
	long long value;
	long long count;
}; 
int l=1,r;
int f=0;
node a[900000],b[900000],m;
int c[1000000],t;
bool cmp(node a,node b){
	if(a.value==b.value)return a.count>b.count;
	return a.value>b.value;
}
int main(){
//兩個數組一個是耽誤的,另一個是未開始的根據兩個數組比較來確定每分鐘誰應該先飛
long long n,k;
cin>>n>>k;
long long sum=0;
for(int i=1;i<=n;i++){
	scanf("%lld",&a[i].value);
	a[i].count=i;
	if(i<=k)
	b[i]=a[i];
}
t=k+1;
for(int i=k+1;i<=n+k;i++){
	if(i<=n){
		if(l<t&&i==k+1)
		sort(b+l,b+t,cmp);
		if(l<t&&b[l].value>a[i].value){
			c[b[l].count]=i;
			sum+=(i-b[l].count)*b[l].value;
			l++;
			b[t++]=a[i];
			for(int i=t-2;i>=l;i--){//時間複雜度爲o(n),仍然超時
				if(b[i].value<b[i+1].value){
					m=b[i];
					b[i]=b[i+1];
					b[i+1]=m;
				}
				else break;
			}
		}
		else {
			c[a[i].count]=i;
//			sum+=(i-a[i].count)*a[i].value;
		}
	}
	else {
		if(f==0)
		sort(b+l,b+t,cmp),f=1;
		if(l<t){
			c[b[l].count]=i;
			sum+=(i-b[l].count)*b[l].value;
			l++;
		}
	}
}
cout<<sum<<endl;
for(int i=1;i<=n;i++)
printf("%lld ",c[i]);
return 0;
}

正確代碼

#include<iostream>
#include<queue>
using namespace std;
struct node{
	long long value;
	long long count;
	friend bool operator <(node a,node b){
		if(a.value==b.value)//注意要使航班耽誤時間儘量少
		return a.count>b.count;
		return a.value<b.value;
	}
}; 
node a[900000],m;
int c[1000000],t;
priority_queue<node>q;
int main(){
//兩個數組耽誤的,未開始的根據兩個數組比較來確定每分鐘誰應該先飛
long long n,k;
cin>>n>>k;
long long sum=0;
int i;
for( i=1;i<=n;i++){
	scanf("%lld",&a[i].value);
	a[i].count=i;
	if(i<=k)
	q.push(a[i]);
}
for(int i=k+1;i<=n+k;i++){
	if(i<=n){
		if(!q.empty()&&q.top().value>a[i].value){
			c[q.top().count]=i;
			sum+=(i-q.top().count)*((q.top()).value);
			q.pop();
			q.push(a[i]);
		}
		else {
			c[a[i].count]=i;
		}
	}
	else {
	     if(!q.empty()){
			c[q.top().count]=i;
			sum+=(i-q.top().count)*(q.top().value);		
			q.pop();
		}
	}
}
cout<<sum<<endl;
for(int i=1;i<=n;i++)
printf("%d ",c[i]);
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章