問題への羅区P2949ソリューション

あなたは、深さ調査貪欲戻りたい場合はポータルを


説明

そこ\(N \)キー仕事、各\(私は\)キー仕事は期限がある\(D_I \)を、各タスクの完了は、利益を得ることができます\(P_I \)をほとんどあなたが得ることができますを行うどのくらいの利益、。

方法

この質問は、単に間違い貪欲なアルゴリズムを考え、背中と貪欲行くことを期待していないときです。最初のキーワードの締め切り、第二の並べ替えのためのキーワードの利益、もう一度統計をに従い。

明らかに、上記の貪欲アルゴリズムは離れてハックが刻印されています。我々は分が次のより高い利益を選択待つ、現在の利益の最初の締め切りを選択することはできませんので、より多くの最適解を得ることができます。

しかし、我々は、この貪欲な戦略間違った理由を発見した現在の最適解が大域的最適解ではないかもしれない、貪欲な思考に戻って明らかにされています。だから我々は、最適なソリューションを維持するヒープと戻って行きます。

問題は2例に分割(すなわち、それは、カットオフ時間を超えていない)の条件が満たされている設定した場合:現在の最適解が良い場合は、元の最適解(ヒープの最上部)比、我々はグローバルな最適解、本来の最適を更新します問題に、逆に、ソリューション、(すなわち戻っポリシー)に、現在の最適な解放を捨てます。条件はアドホックを満たしていない場合は、山に投げ込まれ、現在の最適解を入れて、あなたはグローバルな最適解を更新することができます。

コード

#include<bits/stdc++.h>
#define int long long 
#define Maxn 100010
inline void read(int &x)
{
    int f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
using namespace std;
int n;
struct node
{
    int D,P;
    bool operator <(const node &x)const
    {
        return D<x.D;
    }
}job[Maxn];
priority_queue<int,vector<int>,greater<int> >qu;
signed main()
{
    //  freopen("Job.in","r",stdin);
    //  freopen("Job.out","w",stdout);
    read(n);
    for(int i=1;i<=n;i++)
    {
        read(job[i].D),read(job[i].P);
    }
    sort(job+1,job+n+1);
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(qu.size()>=job[i].D)//符合条件
        {
            if(qu.top()<job[i].P)//当前的最优解比原来的最优解(堆顶)更优秀
            {
                ans-=qu.top();//更新全局最优解
                qu.pop();//把原来的最优解丢出去
                qu.push(job[i].P);//把当前的最优解放进去
                ans+=job[i].P;//更新全局最优解
            }
        }else//不符合条件
        {
            qu.push(job[i].P);//把当前的最优解丢进堆里
            ans+=job[i].P;//更新全局最优解
        }
    }
    printf("%lld",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/nth-element/p/11785043.html