zoukankan      html  css  js  c++  java
  • Supermarket(贪心/并查集)

    题目链接

    原创的博客

    题意:

      超市里有N个商品. 第i个商品必须在保质期(第di天)之前卖掉, 若卖掉可让超市获得pi的利润。

      每天只能卖一个商品。

      现在你要让超市获得最大的利润。

      n , p[i], d[i] 范围都在10000以内 。

    #include<iostream>
    #include<cstdio>
    #include <cctype>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define mem(a,x) memset(a,x,sizeof(a))
    #define se second
    #define fi first
    const ll mod=998244353;
    const int INF= 0x3f3f3f3f;
    const int N=4e5+5;
    
    int n;
    
    priority_queue<int>q;
    vector<int>v[N];
    
    int main()
    {
        while(cin>>n)
        {
            for(int i=1;i<=10001;i++) v[i].clear() ;
            priority_queue<int>empty;
            swap(empty, q); //相当于清空q。 
        
            for(int i=1;i<=n;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                v[y].push_back(x);
            }
            
            int ans=0;
            for(int i=10005;i>=1;i--)
            {
                for(int j=0;j<v[i].size();j++)
                {
                    q.push(v[i][j]);
                }
                if(!q.empty()) 
                {
                    ans+=q.top(); q.pop();
                }
            }
            printf("%d
    ",ans);
        }
    }

     

     

      用另一种贪心的方法来做,先把所有产品按照利润从大到小排序,然后这个把这个放在截止日期那天卖出,并做好标记,如果截至日期那天已经有其他产品占用了,那么可以把这个产品卖出的时间往前推,直到找到可以卖的那一天并标记好。 按照这种思路提交,AC了,不过却用了141 ms。

      用了这个方法之后,再回想了下并查集方法的代码, 所谓的用并查集做,实际上是对上面那种方法的优化!
    用并查集的关键之处是,我们知道按照上面那个方法,假设一个产品a占用了一个日期后,那么如果下次又有一个产品b和产品a的截止日期是相同的,但是那个日期以被占用了,所以就要往前移动1天,那么就可以用并查集进行标记,在a占用了那个日期后,把a的截止日期指向前一个日期,这样的话,可以直接查找到他要占用到哪一个时间。  用了并查集优化后,时间为47MS。


    ---------------------
    作者:shuangde800
    来源:CSDN
    原文:https://blog.csdn.net/shuangde800/article/details/8022068

    #include<iostream>
    #include<cstdio>
    #include <cctype>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define mem(a,x) memset(a,x,sizeof(a))
    #define se second
    #define fi first
    const ll mod=998244353;
    const int INF= 0x3f3f3f3f;
    const int N=4e5+5;
    
    int n;
    
    //vector<int>v[N];
    int vis[N];
    struct node
    {
        int p,d;
    }a[N];
    bool cmp(node x,node y)
    {
        return x.p>y.p || x.p==y.p&&x.d>y.d;
    }
    
    
    int main()
    {
        while(cin>>n)
        {
            for(int i=1;i<=10005;i++) vis[i]=0;
            int maxT=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&a[i].p,&a[i].d);
                if(maxT<a[i].d) maxT=a[i].d;
            }
            sort(a+1,a+1+n,cmp);
            int ans=0;
            for(int i=1;i<=n;i++)
            {
                if(!vis[a[i].d ])
                {
                    vis[a[i].d ]=1;
                    ans+=a[i].p;
                }
                else{
                    for(int j=a[i].d; j>=1;j--)
                    {
                        if(!vis[j])
                        {
                            vis[j]=1;
                            ans+=a[i].p;
                            break;
                        }
                    }
                }
            }
            cout<<ans<<endl;
        }
    }
    无并查集
    #include<iostream>
    #include<cstdio>
    #include <cctype>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define mem(a,x) memset(a,x,sizeof(a))
    #define se second
    #define fi first
    const ll mod=998244353;
    const int INF= 0x3f3f3f3f;
    const int N=4e5+5;
    
    int n;
    int f[N];
    
    struct node
    {
        int p,d;
    }a[N];
    bool cmp(node x,node y)
    {
        return x.p>y.p;
    }
    
    int getf(int x)
    {
        if(x!=f[x])
        {
            f[x]=getf(f[x]);
        }
        return f[x];
    }
    int main()
    {
        while(cin>>n)
        {
            for(int i=1;i<=10005;i++) f[i]=i;
    
            int maxT=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&a[i].p,&a[i].d);
                if(maxT<a[i].d) maxT=a[i].d;
            }
            sort(a+1,a+1+n,cmp);
            int ans=0;
            for(int i=1;i<=n;i++)
            {
                int fa=getf(a[i].d);
                if(fa>0)
                {
                    ans+=a[i].p;
                    f[fa]=fa-1;
                }
            }
            cout<<ans<<endl;
        }
    }
    +并查集
  • 相关阅读:
    当前日志损坏解决一例
    Oracle 1204 RAC failover 测试 (一)
    Logical standby跳过个别SQL不Apply的测试
    Data guard 又出问题了
    CPIO无反应
    回答棉花糖先生关于我说的DB自动增加Index的问题
    SSD硬盘,先不要用在Server上
    ORA00304: requested INSTANCE_NUMBER is busy,终于解决
    .Net运行时的相互关系
    CSS布局探密04
  • 原文地址:https://www.cnblogs.com/thunder-110/p/10426091.html
Copyright © 2011-2022 走看看