【反悔贪心】

【反悔贪心】

排序+枚举一个点+堆维护另一个点

建筑抢修

https://ac.nowcoder.com/acm/problem/20154

思路

按照截止时间从小到大排序,并遍历截止时间
表示在当前的截止时间内,最多能修多少个建筑
如果修建筑所花时间超过了当前的截止时间->把要花最多时间的去掉->大根堆维护

代码

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
const int N=150010;
int n;
struct node{
	int t1,t2;
}a[N];
bool cmp(node x,node y){
	if(x.t2!=y.t2) return x.t2<y.t2;
	return x.t1<y.t1;
}
priority_queue<int> q;
//注意加greater是小根堆 默认大根堆 
signed main(){
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      cin>>n;
      for(int i=1;i<=n;i++) cin>>a[i].t1>>a[i].t2;
      sort(a+1,a+1+n,cmp);
      ll ans=0;
      int cnt=0;
      for(int i=1;i<=n;i++){
      	q.push(a[i].t1);
      	ans+=a[i].t1;
      	cnt++;
      	while(ans>a[i].t2 && q.size()){
      		int t=q.top();
      		q.pop();
      		ans-=t;
      		cnt--;
		}
	}
	cout<<cnt;
      return 0;
}

井然有序之窗

https://ac.nowcoder.com/acm/contest/95323/H

思路

以左端点排序并遍历,用小根堆维护右端点,取出满足条件的最小值->答案一定不会变劣
如果一次遍历取不到答案->整个方案都不行

代码

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int N=100010;
int n;
struct node{
	int l,r,num;
	int size=0;
	bool operator < (const node &x)const{
		return r>x.r;
	}
}a[N];
int nu[N];
bool cmp(node x,node y){
	if(x.l!=y.l) return x.l<y.l; 
	return x.r<y.r;
}
bool is_ok=true;
priority_queue<node> q;
signed main(){
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      cin>>n;
      for(int i=1;i<=n;i++){
      	cin>>a[i].l>>a[i].r;
      	a[i].num=i;
      	a[i].size=a[i].r-a[i].l+1;
	}
	sort(a+1,a+1+n,cmp); 
	int p=1;
	for(int i=1;i<=n;i++){//枚举排列的每个数 
		while(p<=n && a[p].l<=i) q.push(a[p++]);
		if(!q.size() || q.top().r<i){
			is_ok=false;
			break;
		}
		nu[q.top().num]=i;
		q.pop();//用完记得弹出 
	}
	if(is_ok){
		for(int i=1;i<=n;i++) cout<<nu[i]<<" ";
	}else cout<<"-1";
      return 0;
}

小O爱论文

https://fjnuacm.top/d/contest/p/P2401B?tid=66f7ba21703d6adf52eb4190

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
const int N=100010;
int t; 
int n,m;
int x[N],y[N];
void solve(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>x[i];
	for(int i=1;i<=n;i++) cin>>y[i];
	ll lin=0;
	priority_queue<int> q;
	for(int i=1;i<=n;i++){
		lin+=x[i];
		q.push(y[i]);
		//默认每个都阅读
		lin-=y[i];
		//如果当前精力值不够,就把之前花得最多的弹出去,直到精力值恢复 
		while(lin<0){
			int t=q.top();
			q.pop();
			lin+=t;
		}
		//如果已经到达了阅读数 也需要优化
		while(q.size()>m){
			int t=q.top();
			q.pop();
			lin+=t;
		}
	}
	int ans=q.size();
	if(ans>=m){
		cout<<"YES"<<endl; 
		cout<<lin<<endl;
	}
	else{
		cout<<"NO"<<endl; 
		cout<<ans<<endl;
	}
}
signed main(){
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      cin>>t;
      while(t--){
      	solve();
	}
      return 0;
}

Serval and Kaitenzushi Buffet

https://codeforces.com/contest/2085/problem/D
对应吃的点取最大即可

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
int t;
int n,k;
void solve(){
      cin>>n>>k;
      vector<int> d(n+1);
      for(int i=1;i<=n;i++) cin>>d[i];
      //只能拿n-k前的
      //最多拿几个
      int cnt=n/(k+1);
      //反悔贪心:在正好能吃完的地方(注意这里 拿值的条件)拿走之前最大的
      /*eg
      n=6 k=3
      6 5 4 3 2 1
      √     √
      */
      priority_queue<int> q;
      ll ans=0;
      for(int i=1;i<=n;i++){
            q.push(d[i]);
            if((n-i+1)%(k+1)==0){
                  ans+=q.top();
                  q.pop();
            }
      }
      cout<<ans<<endl;
}
signed main(){
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      cin>>t;
      while(t--) solve();
      return 0;
}
posted @ 2025-01-23 09:52  White_ink  阅读(4)  评论(0)    收藏  举报