[kuangbin帶你飛]專題五 並查集---poj1456(貪心+並查集 || 貪心加堆優化) &&& 計算智能恰水果

G - Supermarket POJ - 1456

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

題意:

有n個選擇,每次選擇權重最大的(且這次選擇不和之前的時間衝突,最優選擇,就取它所能取得最大時間)

思路:

貪心,這裏介紹兩種貪心法。

反思(並查集)

  1. 把題目的每個時間點轉化爲一個節點。(此時不知道題目的最大時間,所以全部初始化爲-1,find時也用-1判定)
  2. 每次選了一個最優的,就把那個時間點的父親變爲A-1。算是把A這個時間給用了,後面不會用
	    int A=find(p[i].dead);
            if(A>0)
            {
                ans+=p[i].pa;
                f[A]=A-1;//這一步
            }

AC(堆優化)

#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdio>
#define mst(x,a) memset(x,a,sizeof(x))
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
const int maxn=1e4+10;
typedef long long ll;
struct point
{
    int v;
    int dead;
    bool operator <(const point &x)const
    {
        return v<x.v;
    }
}p[maxn];
bool cmp(point a,point b)
{
    return a.dead>b.dead;
}
priority_queue<point>q;
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        while(!q.empty())q.pop();
        int max_day=0;
        For(i,1,n)
        {
            scanf("%d%d", &p[i].v,&p[i].dead);
            max_day=max(max_day,p[i].dead);
        }
        sort(p+1,p+1+n,cmp);
        ll ans=0,cnt=1,sum=0;
        for(int i=max_day; i>=1; i--)
        {
            while(cnt<=n&&p[cnt].dead>=i)q.push(p[cnt++]);
            if(!q.empty())
            {
                ans+=q.top().v;
                q.pop();
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

AC(並查集,首選,複雜度低)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
#define mst(x,a) memset(x,a,sizeof(x))
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
struct point
{
    int pa,dead;
}p[maxn];
bool cmp(point a,point b)
{
    return a.pa>b.pa;
}
int f[maxn];
int find(int x)
{
    if(f[x]==-1)return x;
    return f[x]=find(f[x]);
}
int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        mst(f,-1);//未知最大時間,全部初始化爲-1,相應的find裏要改成-1
        For(i,1,n)scanf("%d%d", &p[i].pa,&p[i].dead);
        ll ans=0;
        sort(p+1,p+1+n,cmp);
        For(i,1,n)
        {
            int A=find(p[i].dead);
            if(A>0)
            {
                ans+=p[i].pa;
                f[A]=A-1;
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章