题目大意:给定n个灯泡和n个房间,每个灯泡有一个功率,每个房间有一个照亮的最小功率,可以换k个灯泡,求照亮所有房间的最小功率
将灯泡的功率和房间的最小功率排序,从大到小扫描每个房间
对于一个房间,首先将能照亮这个房间的灯泡都加入堆
如果堆为空则花掉一次换灯泡的机会换一个功率为这个房间的最小功率的灯泡
否则取走功率最小的灯泡照亮这个房间,并将灯泡功率与房间最小功率的差值加入另一个堆
结束时如果还有换灯泡的机会,就把第二个堆中最大的k个差值换掉
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 500500 using namespace std; struct Heap{ int heap[M],top; void Insert(int x) { heap[++top]=x; int t=top; while(t>1) { if(heap[t]>heap[t>>1]) swap(heap[t],heap[t>>1]),t>>=1; else break; } } void Pop() { heap[1]=heap[top--]; int t=2; while(t<=top) { if( t<top && heap[t+1]>heap[t] ) ++t; if(heap[t]>heap[t>>1]) swap(heap[t],heap[t>>1]),t<<=1; else break; } } }heap1,heap2; int n,k,a[M],b[M]; long long ans; int main() { int i,j; cin>>n>>k; for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=n;i++) scanf("%d",&b[i]); sort(a+1,a+n+1); sort(b+1,b+n+1); for(i=n,j=n;i;i--) { for(;j&&a[j]>=b[i];j--) heap1.Insert(-a[j]); if(!heap1.top) { k--;ans+=b[i]; if(k==-1) return puts("NIE"),0; } else { int x=-heap1.heap[1];heap1.Pop(); ans+=x; heap2.Insert(x-b[i]); } } while(k--) ans-=heap2.heap[1],heap2.Pop(); cout<<ans<<endl; return 0; }
BZOJ 3728 PA2014Final Zarowki 堆+贪心
原文地址:http://blog.csdn.net/popoqqq/article/details/44040281