[CTSC2007] 挂缀pendant
反悔贪心
据说是板子
但我还是想了挺久
题意可以抽象成给 \(N\) 个区间然后给出每个区间的左端点最右能在哪个位置,和区间的长度,问最多能选多少个不重叠的区间,并且区间长度最小。
我们可以在多加一个数组 \(R_i\) 表示最晚什么时候结束,\(R_i=W_i+C_i\)。
然后我们进行贪心,从前往后枚举,如果当前的区间长度加上总区间长度小于当前区间的 \(R_i\),那么当前区间就可以被选择。
由于要求总区间长度最小,所以反之我们需要将当前区间长度与已选区间中的最长者作比较,如果当前区间长度小于最长区间,那么用当前区间代替最长区间。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct inv{
int len,l,r;
friend bool operator <(inv x,inv y){return x.r<y.r;}
}a[200001];
int n,len,sum;
priority_queue<int>q;
signed main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i].l>>a[i].len,a[i].r=a[i].len+a[i].l;
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
if(sum+a[i].len<=a[i].r)len++,sum+=a[i].len,q.push(a[i].len);//新的区间
else if(q.top()>a[i].len)sum-=q.top(),q.pop(),q.push(a[i].len),sum+=a[i].len;//可以替代原来的最大
}
cout<<len<<'\n'<<sum;
return 0;
}

浙公网安备 33010602011771号