http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11560&courseid=0spa
題意:總共有n天,天天yangyang都須要一個快樂值,有m個隊友,每一個隊友都會給陽陽一個快樂值(爲2的冪),而且只能給一次,若是某一天隊友給的快樂值達到yangyang須要的快樂值那麼這一天yangyang就是快樂的,統計最多快樂的天數。code
思路:由於達到快樂的天數不要求連續,那麼只要對須要的快樂值和隊友給的快樂值分別排序,而後每次二分出一個快樂的天數x,判斷能不能用m個數去知足它,因此把0到x的數加入優先隊列,而後從m開始從大到小去覆蓋優先隊列的值.blog
1 #include<cstdio> 2 #include<queue> 3 #include<algorithm> 4 using namespace std; 5 6 int n,m,h[20010],p[20010]; 7 8 bool ok(int x) 9 { 10 priority_queue<int>que; 11 for(int i=0;i<x;i++) 12 que.push(h[i]); 13 int y=m; 14 while(!que.empty()) 15 { 16 y--; 17 if(y<0) break; 18 if(p[y]<que.top()) que.push(que.top()-p[y]); 19 que.pop(); 20 } 21 return que.empty(); 22 } 23 void solve() 24 { 25 int lb=0,ub=n; 26 int cnt=0; 27 while(lb<=ub) 28 { 29 int mid=(lb+ub)>>1; 30 if(ok(mid)) 31 { 32 lb=mid+1; 33 cnt=max(cnt,mid); 34 // printf("%d %d\n",cnt,lb); 35 } 36 else ub=mid-1; 37 } 38 printf("%d\n",cnt); 39 } 40 int main() 41 { 42 //freopen("a.txt","r",stdin); 43 while(~scanf("%d%d",&n,&m)) 44 { 45 for(int i=0;i<n;i++) scanf("%d",&h[i]); 46 for(int i=0;i<m;i++) scanf("%d",&p[i]); 47 sort(h,h+n); 48 sort(p,p+m); 49 solve(); 50 } 51 return 0; 52 }