【贪心】【反悔贪心】反悔堆
【贪心】【反悔贪心】反悔堆
带反悔的贪心就比如你在挑选一些商品的时候,你在已经购入了一定的商品的时候,你突然发现一个性价比更高的同类商品,你会选择退掉当前已有商品中性价比最低的商品,来腾出位置给这个性价比更高的商品。
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;
}
CF865D Buy Low Sell High
题意
给出一支股票连续n天的价格,每天只能买入它,或者卖出它,或者什么都不干。
求n天结束后能获得的最大利润。
思路
若在第x天买入,并且将其压入一个专门用于买入的堆中。
则在后面的y天考虑将其卖出(只有在\(x_{price}<y_{price}\)),则会获得\(y_{price}-x_{price}\)的利润。
而如果在更后面的第y‘天将第x天的股票卖出能大于比在第y天卖出的利润来得大得话,那么就应该调整为在第y’天卖出(当且仅当\(y'_{price}>y_{price}\))。
原本只能赚\(y_{price}-x_{price}\),现在却能够赚\(y’_{price}-x_{price}\)
对于总利润的更新量为\(y'_{price}-y_{price}\),也就是说我们是在y的基础上继续考虑y‘,不妨我们直接向堆中继续压入y,如果后面的一个y’有一定缘分能够将y给取出,可以直接视为将对于同一个买入点x,将卖出点y修改为y‘。
注意如果是这种情况下取出y是将y替换为y’,即将y作为卖入点给取消掉。
而y也可以作为一个买入点,所以还是需要向堆中再压入一个y。
#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;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
priority_queue<int,vector<int>,greater<int> > pq;
ll sum = 0;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
if(!pq.empty()&&x>pq.top()) sum += x - pq.top(),pq.pop(),pq.push(x);
pq.push(x);
}
cout<<sum;
return 0;
}