洛谷P4653 [CEOI2017]Sure Bet
阿新 • • 發佈:2020-12-01
題目
https://www.luogu.com.cn/problem/P4653
思路
最大化可能的最小收益,最大值最小,想必大家已經熟悉二分題的這個套路了。列舉一個值x,模擬,檢驗是否能選A和選B的收益都達到x。
顯然要先選權值大的燈,所以我們降序排序。
關於這個檢驗,我用的是最暴力的方法,若A不行,就加到它行;再看B,也是如此。注意因為選取燈泡有花費,成本變高,這時A又不一定可行了,之後我們反覆橫跳,直到AB都滿足條件。
若可以出現AB都滿足的情況,則該x值可行。
程式碼
#include<cstdlib> #include<algorithm> #define inf 0x3f3f3f3f #define eps 1e-6 #define maxn (int)(1e6+10) #define db double using namespace std; int n; db a[maxn],b[maxn]; int ok(db x){ int i=0,j=0; db suma=0,sumb=0; while(suma-i-j<x||sumb-i-j<x){ while(suma-i-j<x){ if(i>n) return 0; suma+=a[++i]; } while(sumb-i-j<x){ if(j>n) return 0; sumb+=b[++j]; } } return 1; } bool cmp(db x,db y){ return x>y; } int main(){ int i,j; db l,r,mid; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%lf%lf",&a[i],&b[i]); sort(a+1,a+n+1,cmp); sort(b+1,b+n+1,cmp); l=0;r=inf; while(r-l>eps){ mid=(l+r)/2.0; if(ok(mid)) l=mid; else r=mid; } printf("%.4lf",l); // system("pause"); return 0; }