• POJ 1456 Supermarket(贪心+并查集优化)


    一开始思路弄错了,刚开始想的时候误把所有截止时间为2的不一定一定要在2的时候买,而是可以在1的时候买。

    举个例子:

    50 2  10 1   20 2   10 1    50+20

    50 2  40 4   30 4   20 1  10 1      20+50+30+40

    思路:用优先级队列,每次取价格最大的(如果价格相同,取截止时间最大的)。      

       然后往1~maxdx里加,首先看它截止时间上的位置是否已经存在其他物品,如果不存在,就加到该处。      

       如果存在,就往前判断,直到有一处空位没被占用,就加入到该位置。

          后来网上看了一下,可以用并查集查找不冲突的时间点

          不用并查集优化,110ms;用并查集后,63ms

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    const int maxn=10001;
    
    int n;
    int vis[maxn]; //若vis[i]=1,表示此处已经有物品,即有物品在i时刻卖出
    int maxdx=0;  //用于记录所有物品中最大的截止时间
    int f[maxn];
    struct Product{
        int price,deadtime;
    
        bool operator <(const Product tmp) const{
            if(price==tmp.price)
                return deadtime<tmp.deadtime;
            else
                return price<tmp.price;
        }
    };
    
    void init(){
        for(int i=0;i<=maxdx;i++){
            f[i]=i;
        }
    }
    int find_root(int x){
        if(f[x]!=x)
            f[x]=find_root(f[x]);
        return f[x];
    }
    int main()
    {
    
        int p,d;
        int ans,counts;
        Product tmp;
        while(scanf("%d",&n)!=EOF){
            priority_queue<Product> q;
            maxdx=0;
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=n;i++){
                scanf("%d%d",&p,&d);
                if(d>maxdx)
                    maxdx=d;
                tmp.price=p;
                tmp.deadtime=d;
                q.push(tmp);
    
            }
            init();
            ans=0;
            counts=0;  //用于记录所卖的物品个数,如果个数为maxdx,表明1~maxdx中的所有时刻都已有物品在卖
            while(counts<maxdx && !q.empty()){
                tmp=q.top();
                q.pop();
                if(vis[tmp.deadtime]==0){
                    ans+=tmp.price;
                    vis[tmp.deadtime]=1;
                    f[tmp.deadtime]=tmp.deadtime-1;   //刚开始这里忘写了,导致WA
                    counts++;
                }
                else{
                    int t=tmp.deadtime;
                    int pos=find_root(t);
                    if(pos>0){
                        vis[pos]=1;
                        counts++;
                        ans+=tmp.price;
                        f[pos]=pos-1;
                    }
                    /*
                    while(vis[t]==1){
                        t--;
                    }
                    if(t>0){
                        vis[t]=1;
                        ans+=tmp.price;
                        counts++;
                    }
                    */
                }
    
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    MyBatis3.2从入门到精通第一章
    (转)浅析Java中的访问权限控制
    mysql添加索引命令
    (转)浅谈Java中的对象和对象引用
    (转)String、StringBuffer与StringBuilder之间区别
    (转)浅谈Java中的equals和==
    Java并发编程:Lock
    Java并发编程:synchronized
    安装MySQL
    Excel常用函数
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3291171.html
Copyright © 2020-2023  润新知