1. 程式人生 > 其它 >【貪心】【反悔貪心】反悔堆

【貪心】【反悔貪心】反悔堆

【貪心】【反悔貪心】反悔堆

帶反悔的貪心就比如你在挑選一些商品的時候,你在已經購入了一定的商品的時候,你突然發現一個性價比更高的同類商品,你會選擇退掉當前已有商品中價效比最低的商品,來騰出位置給這個價效比更高的商品。

P2949 [USACO09OPEN]Work Scheduling G

題意

有n份工作,每份工作的完成需要耗費1個單位時間,且每份工作有一個截止時間,同時每份工作完成後會得到對應的報酬,求如何選擇工作使得最後能夠獲得的最大利潤最高。

思路

我們可以將我們要安排的工作放入到一個容器中,且當前容器大小代表著說當前要完成的數量,也可以通過它得到對應的時間(每一項工作耗費一個單位時間)。

如果加入的任務的截止時間小於等於這個容器的大小,也就是說要麼刪去其中一個價值最小的任務來將這個任務塞進容器中,要麼將這個任務給忽略掉。具體要和當前容器中最小价值的任務進行比較。

  • 如果我們按照時間進行排序的話,越往後面考慮的任務的截止時間越晚,也就是說後面任務的對應的時間滿足其前面所有的任務。

而如果加入的任務的截止時間大於這個容器的大小,我們就可以直接將其加入。

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define MAX 1000005
#define MOD 1000000007
using namespace std;
const int N = 3E5+5,M = 6E5+10;
int n,m;
struct task{
	int ddl;
	ll pri;
}ts[N];
bool cmp(task &a,task &b)
{
	return a.ddl<b.ddl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    priority_queue<int,vector<int>,greater<int> > pq;
	for(int i=1;i<=n;i++) 
		cin>>ts[i].ddl>>ts[i].pri;
	sort(ts+1,ts+n+1,cmp);
	ll sum = 0;
	for(int i=1;i<=n;i++)
	{
		if(ts[i].ddl>pq.size())
		{
			sum += ts[i].pri;
			pq.push(ts[i].pri);
		}
		else if(ts[i].pri>pq.top())
		{
		    sum -= pq.top();pq.pop();
			sum += ts[i].pri;pq.push(ts[i].pri);	
		}
	}
	cout<<sum;
    return 0;
}