生日礼物&&Supermarket
Solution1
可以通过堆来实现,按照过期时间排序,优先处理过期时间短的,等到没办法塞进去的时候弹出堆顶,最后就是所有的取法
#include<bits/stdc++.h> using namespace std; int n; struct node{int p,d;}a[10005]; bool cmp(node a,node b){return a.d<b.d||(a.p<b.p&&a.d==b.d);} priority_queue<int,vector<int>,greater<int> > q; int main(){ while(scanf("%d",&n)==1){ for(int i=1;i<=n;i++) scanf("%d %d",&a[i].p,&a[i].d); sort(a+1,a+n+1,cmp); int sum=0; for(int i=1;i<=n;i++){ if(a[i].d==sum)q.pop(),q.push(a[i].p); else if(a[i].d>sum) q.push(a[i].p),++sum; } int ans=0; while(!q.empty())ans+=q.top(),q.pop(); printf("%d\n",ans); } }
Solution2
可以通过链表+贪心实现,先把价值最高的放在最后,不浪费,之后再利用链表考虑前面的
#include<bits/stdc++.h> using namespace std; struct node{int qx,c;}a[1000005]; bool cmp(node a,node b){return a.c>b.c;} int pre[1000005],n,ans; bool b[1000005]; int find(int k){ if(!b[k]||!k)return k; return pre[k]=find(pre[k]); } int main(){ srand(20050628); freopen("homework.in","r",stdin); freopen("homework.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&a[i].qx,&a[i].c); sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++) pre[i]=i-1; for(int i=1;i<=n;i++){ int tmp=find(a[i].qx); if(tmp){ b[tmp]=true; ans+=a[i].c; pre[a[i].qx]=pre[tmp]; } } cout<<ans<<endl; return 0; }