Solution
由题目可知要求一个集合,使集合大小满足元素的限制且元素之和最大。
一个显然的贪心思想:在满足条件的前提下使得和最大。要求和最大,就可以使用堆来维护。
因此,可以先按 从大到小排序,维护一个小根堆,每插入新元素之前,将堆的大小调整至符合条件。再实时维护一个集合内元素的最大值即可。
时间复杂度:
最后,给大家推荐一道类似的题目:Supermarket
也是维护一个小根堆进行贪心。
Code
#include <iostream> #include <cstdio> #include <algorithm> #define ll long long using namespace std; const int maxn=1e5+10; struct node{ int v; int s; }a[maxn],heap[maxn]; int n,tot; ll ans,sum; bool cmp(node x,node y){ return x.s>y.s; } void up(int x){ while(x>1){ if(heap[x>>1].v>heap[x].v) swap(heap[x>>1],heap[x]); else break; x>>=1; } } void down(int x){ int y=x<<1; while(y<=tot){ if(y<n&&heap[y+1].v<heap[y].v) y++; if(heap[y].v<heap[x].v) swap(heap[x],heap[y]); else break; x=y; y=x<<1; } } void Insert(node p){ heap[++tot]=p; up(tot); } void Extract(){ heap[1]=heap[tot--]; down(1); } int main(){ cin>>n; for(int i=1;i<=n;i++) cin>>a[i].v>>a[i].s; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++){ while(tot>=a[i].s){ sum-=heap[1].v; Extract(); } Insert(a[i]); sum+=a[i].v; ans=max(ans,sum); } cout<<ans; return 0; }