CF Hello World 2018 913D SOL
题目大意:
给你X门学科,每一门学科有两个参数,ti和·ai,我们想通过一门学科只有满足以下2个条件:
1.其尝试考试的simga ti <=T;
2.其尝试考试的次数<=ai
求最多通过的学科数,并输出方案。
SOL:
我们发现如果我们有考试却没有通过,我们还不如不考。
我们又发现其满足二分性质。那么我们就二分答案。
#include<bits/stdc++.h> #define sight(c) ('0'<=c&&c<='9') #define N 400007 inline void read(int &x){ static char c;static int b; for (b=1,c=getchar();!sight(c);c=getchar())if (c=='-') b=-1; for (x=0;sight(c);c=getchar()) x=x*10+c-48; x*=b; } struct Node{ int a,t,id; bool operator < (const Node& T)const { return t<T.t; } }t[N]; using namespace std; int T,n,r,ans,Ans,tot; inline bool check(int x){ tot=Ans=0; for (int i=1;i<=n;i++) if (t[i].a>=x) { Ans+=t[i].t;tot++; if (tot==x) break; } return tot==x&&Ans<=T; } int main () { //freopen("a.in","r",stdin); read(n); read(T); for (int i=1;i<=n;i++) read(t[i].a),read(t[i].t),t[i].id=i; r=trunc(log2(n));r=1<<r; sort(t+1,t+n+1); while (r) { if (check(ans+r)) ans+=r; r>>=1; } printf("%d\n",ans); printf("%d\n",ans); tot=0; if (!ans) return 0; for (int i=1;i<=n;i++) { if(t[i].a>=ans) {printf("%d ",t[i].id);tot++;} if (tot==ans) break; } return 0; }