生日礼物&&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;
}

 

posted @ 2019-08-24 22:30  Coder_cjh  阅读(123)  评论(0编辑  收藏  举报