luogu P5909 [CTSC2007]挂缀pendant
题面传送门
考试时盯着这个看了很久然后以为是只能连续选一段于是爆零了。光荣成为唯一一个没有通过的人。
首先先将右端点排序。
然后依次加入。
如果能加入就加入。
如果不能,那么就找到最大的比较,如果可以就加进去并把最大的弹出来。
这个过程可以用堆维护。
时间复杂度\(O(nlogn)\)
code:
#include<cstdio>
#include<queue>
#include<algorithm>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define beg(x) int cur=s.h[x]
#define end cur
#define go cur=tmp.z
#define l(x) x<<1
#define r(x) x<<1|1
#define N 200039
#define ll long long
#define ui unsigned int
using namespace std;
int n,m,k,now,tot;
struct ques{ll a,b,w;}s[N];
I bool cmp(ques x,ques y){return x.w<y.w;}
priority_queue<int> q;ll ans;
int main(){
register int i,j;
freopen("pendant.in","r",stdin);
freopen("pendant.out","w",stdout);
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%lld%lld",&s[i].a,&s[i].b),s[i].w=s[i].a+s[i].b;sort(s+1,s+n+1,cmp);
for(i=1;i<=n;i++){
if(ans+s[i].b<=s[i].w)ans+=s[i].b,tot++,q.push(s[i].b);
else now=q.top(),s[i].b<now&&(q.pop(),q.push(s[i].b),ans+=s[i].b-now);
}
printf("%d\n%lld\n",tot,ans);
}

浙公网安备 33010602011771号