日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NOI.AC-保镖【贪心,对顶堆】

發布時間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NOI.AC-保镖【贪心,对顶堆】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:http://noi.ac/contest/266/problem/795


題目大意

nnn個人第iii個巡邏一次aia_iai?秒,休息至少bib_ibi?秒。
要求

  • 任意時刻都有人巡邏
  • 在一個人的兩次相鄰的巡邏直接不能有另一個人巡邏兩次。

  • 解題思路

    對于性質二我們發現就是在nnn個人里選擇最少的人輪流巡邏使得任意時刻都有人巡邏。

    我們考慮貪心,將人按照bib_ibi?排序,然后枚舉就好了,這樣我們就確定了最大的bib_ibi?,所以我們要求前面的最大的數的和使得它的和足夠就好了。

    但是這樣我們會發現有許多問題,因為這個人兩次巡邏的間隔是不計算自己的巡邏時間的,
    也就是sum?ai>bi?sum>bi+aisum-a_i>b_i\Rightarrow sum>b_i+a_isum?ai?>bi??sum>bi?+ai?

    所以我們改為按照bi+aib_i+a_ibi?+ai?排序就好了,然后對頂堆維護前若干個最大值使得他們的和滿足max{bi+ai}max\{b_i+a_i\}max{bi?+ai?}


    codecodecode

    #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define ll long long using namespace std; const ll N=5e5+10; struct node{ll t,b; }a[N]; ll n,sum,z,ans=2147483647; priority_queue<ll> q1,q2; bool cmp(node x,node y) {return x.b==y.b?x.t<y.t:x.b<y.b;} int main() {//freopen("data.in","r",stdin);scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld%lld",&a[i].t,&a[i].b);a[i].b+=a[i].t;}sort(a+1,a+1+n,cmp);for(ll i=1;i<=n;i++){if(q1.empty()||a[i].t>-q1.top()){q1.push(-a[i].t);sum+=a[i].t;z++;}else q2.push(a[i].t);while(!q1.empty()&&sum>=a[i].b){sum+=q1.top();z--;q2.push(-q1.top());q1.pop();}while(!q2.empty()&&sum<a[i].b){sum+=q2.top();z++;q1.push(-q2.top());q2.pop();}if(sum>=a[i].b){ans=min(ans,z);}}if(ans==2147483647) printf("-1");else printf("%lld",ans); }

    總結

    以上是生活随笔為你收集整理的NOI.AC-保镖【贪心,对顶堆】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。