Supermarket(贪心/并查集)

 

题目链接

原创的博客

 

题意:

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

  每天只能卖一个商品。

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

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

 

 

#include
#include
#include 
#include
#include
#include
#include<string>
#include
#include<set>
#include
#include
#include
#include
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)
            {
                q.push(v[i][j]);
            }
            if(!q.empty()) 
            {
                ans+=q.top(); q.pop();
            }
        }
        printf("%d\n",ans);
    }
}

 

 

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

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


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

#include
#include
#include 
#include
#include
#include
#include<string>
#include
#include<set>
#include
#include
#include
#include
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;

//vectorv[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(maxTa[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<endl;
    }
}
无并查集

 

#include
#include
#include 
#include
#include
#include
#include<string>
#include
#include<set>
#include
#include
#include
#include
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(maxTa[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<endl;
    }
}
+并查集

 

转载于:https://www.cnblogs.com/thunder-110/p/10426091.html

你可能感兴趣的:(Supermarket(贪心/并查集))