P4053 [JSOI2007] 建筑抢修
tag:贪心,堆
一个堆A以 T2 为关键字 从小到大排序,另一个堆B记录 已维修的 的建筑的维修时间,用 cnt 记录总的维修时间(时刻?)
两种情况:
- 若可以维修,cnt 加下维修时间。
- 若不可以维修,从B中获取最大值mav, 还是两种情况,(1)满足 mav>t1 && cnt-mav+t1<=t2的条件,将mav弹出B,t1 弹入 B,cnt=cnt-mav+t1,这样虽然不能对答案产生共享,但可以节省时间;(2)若不满足条件,则继续
核心代码:
struct node
{
LL t1,t2;
LL jianduan;
bool operator <(const node &c) const
{
if(t2==c.t2)
return t1>c.t1;
return t2>c.t2;
}
};
void solve()
{
priority_queue<node> q;
priority_queue<LL,vector<LL>,less<LL>> ever;
int n; cin>>n;
for(int i=1;i<=n;i++)
{
LL x,y; cin>>x>>y;
struct node f;
f.t1=x,f.t2=y;
f.jianduan=y-x;
q.push(f);
}
LL cnt=0;int ans=0;
for(int i=1;i<=n;i++)
{
struct node t = q.top();
q.pop();
if(cnt+t.t1<=t.t2)
{
ans++;
ever.push(t.t1);
cnt+=t.t1;
}
else if(cnt+t.t1>t.t2)
{
int tt=ever.top();
if(tt>t.t1&&cnt-tt+t.t1<=t.t2)
{
cnt-=tt;
cnt+=t.t1;
ever.pop(); ever.push(t.t1);
}
}
}
cout<<ans<<endl;
return;
}
int main()
{
std::ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr);
//int T;cin>>T;for(int i=1;i<=T;i++)
solve();
return 0;
}
本文来自博客园,作者:magicat,转载请注明原文链接:https://www.cnblogs.com/magicat/p/16566709.html