zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    SecureCRT设置linux终端显示颜色
    OpenCV空洞填充算法
    祝贺自己的软件《万能数据库查询分析器》在非凡软件站和太平洋电脑的下载排行榜分别名列第1和第2
    linux磁盘分区 简要
    linux压缩解压命令
    【可视化】Echarts3坐标系倒映
    【可视化】Echarts3 在世界地图中绘制中国各省份的轮廓
    【Maven】解决linux下安装maven update-alternative --display mvn链接层数过多
    【Ubuntu 16】启动Eclipse Indigo报错 error code1 jdk没有配置好
    oracle体系结构
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3291171.html
Copyright © 2011-2022 走看看