关于后悔贪心

推荐一个大佬的文章【学习笔记】反悔贪心 - Koshkaaa (cnblogs.com)

建筑抢修

这个我一开始试图写二分的最长上升子序列,然后翻车了,乐。

这个题目我们按照报废时间升序排列,然后直接贪心的话可能会出现如果先修某个也能修成当前答案个而且耗时更少,只是因为报废时间长而没有贪心到的情况。

用大根堆堆顶是维护此时可行且耗时最多的。每次我们先把它加入堆。然后判断能不能修,如果不能修就弹出耗时最多的。如果它不是耗时最长的,那么就会达成后悔贪心的效果,由于我们是按照截止时间的升序排列的,保证后悔贪心的建筑此时一定是不会报废的(我们假设此时耗时最长的是i,耗时ki,截止时间是ti,那么此时加入的kj一定是小于ki的,而且我们按照报废时间升序排列,保证tj>ti,也就是说我们用j建筑替换i建筑的位置,总耗时会减少,i建筑能修完的,j建筑也必然能修完)。

查看代码
 #include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;

struct bui
{
	int a,b;
	bool operator<(bui x)const
	{
		return a<x.a;
	}
}c[150005];
priority_queue<bui>ax;
ll n,t=0;
int ans;
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>c[i].a>>c[i].b;
	sort(c+1,c+1+n,[](bui x,bui y)->bool{return x.b<y.b;});
	for(int i=1;i<=n;i++)
	{
		ax.push(c[i]);
		t+=c[i].a;
		if(t<=c[i].b)
		{
			ans++;
		}
		else
		{
			t-=ax.top().a;
			ax.pop();
		}
	}
	cout<<ans;
	return 0;
}

 

posted @ 2023-08-12 08:53  qbning  阅读(11)  评论(0编辑  收藏  举报
描述