赞
踩
本专题主要是关于利用优先队列解决贪心选择上的“反悔”问题
话不多说,直接看题:

下面为分析:
很显然,我们在整体上以s[i]为基准,先把士兵按s[i]排好。然后,我们先求s[i]大的开始,即规定选人数不超过s[i]的士兵,下面为图解:

下面为AC代码:
- #include<bits/stdc++.h>
- using namespace std;
- struct node{
- long long v,s;
- }a[1000100];
- long long n;
- bool cmp(node a,node b){
- return a.s>b.s;
- }
- signed main(){
- cin>>n;
- for(int i=1;i<=n;i++){
- scanf("%lld%lld",&a[i].v,&a[i].s);
- }
- sort(a+1,a+1+n,cmp);
- priority_queue<long long,vector<long long>,greater<long long> > q;
- long long cap=a[1].s,sum=a[1].v,max1=-1;
- q.push(a[1].v);
- for(int i=2;i<=n;i++){
- if(a[i].s==cap){
- q.push(a[i].v);
- sum+=a[i].v;
- if(q.size()>cap){
- sum-=q.top();
- q.pop();
- }
- }
- else{
- cap=a[i].s;
- q.push(a[i].v);
- sum+=a[i].v;
- while(q.size()>cap){
- sum-=q.top();
- q.pop();
- }
- }
- max1=max(max1,sum);
- }
- cout<<max1;
- }

再来一道类似的:

下面为分析:
类似的,我们指定一个基准,我们按deadline升序排好,从小的开始枚举。
如果前面的时间加当前所需没超当前建筑的deadline,我们就添加。
否则,我们用它与前面所需时间max的比,如果比他小就替换。
下面为AC代码:
- #include<bits/stdc++.h>
- using namespace std;
- #define int long long
- int n;
- struct node{
- int t1,t2;
- }a[150010];
- bool cmp(node a,node b){
- return a.t2<b.t2;}
- signed main(){
- scanf("%d",&n);
- for(int i=1;i<=n;i++) scanf("%d%d",&a[i].t1,&a[i].t2);
- sort(a+1,a+n+1,cmp);
- priority_queue<int> q;
- int dead=-1,cnt=0,sum=0;
- for(int i=1;i<=n;i++){
- q.push(a[i].t1);
- cnt++;
- sum+=a[i].t1;
- if(a[i].t2!=dead) dead=a[i].t2;
- if(sum>dead){
- sum-=q.top();
- cnt--;
- q.pop();
- }
- }
- cout<<cnt;
- }

让我们总结一下,本专题围绕利用优先队列解决贪心选择上的“反悔”(或优化)问题(常用于固定枚举一个基准值)
最后,举个形象的例子:我们的成长就是从一开始的幼稚不断地经历岁月的打磨,见识的增长,不断优化,最终走向成熟。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。