TOJ 3584. Chocolate Eating 【二分+枚举】

          这道题感觉很好。大意是一头母牛受到了N个公牛送的巧克力(@@),然后母牛决定安排一个合理的吃巧克力方案。母牛最开始的时候心情值为0,每个巧克力有一个快乐值,母牛吃了后心情就加上这个快乐值。但是每天早上母牛的心情值都会变为前一天晚上的一半。现在给出N和N块巧克力的快乐值,和母牛打算吃完这些巧克力的天数D,安排一个合理的方案,使母牛在这D天里心情值最小的值最大。(母牛按顺序吃)

          比如N = 5,D = 5 ,巧克力的快乐值分别为10,40,13,22,7,那么合理的方案应该是

  Day  Wakeup happiness   Happiness from eating   Bedtime happiness
1 0 10+40 50
2 25 --- 25
3 12 13 25
4 12 22 34
5 17 7 24
所以答案应该是24.每个巧克力被吃的天数分别为1,1,3,4,5。
解法就是二分枚举可行解,然后判断这些巧克力能否满足这个解,最后根据找到的最优解来找每个巧克力被吃的天数。
           #include <cstdio> #include <cstring> #define MAXN 50002 using namespace std; int a[MAXN],N,D; long long sum; inline bool work(long long key){ long long idex = 1,pre = 0; for(int i = 1;i <= D; ++i){ pre /= 2; //早上心情值减半 while(pre < key && idex <= N) // 一直吃直到达到key值 pre += a[idex++]; if(pre < key) return false; //如果有一天达不到,不满足 } return true; } int main() { sum = 0; scanf("%d%d",&N,&D); for(int i = 1;i <= N; ++i){ scanf("%d",&a[i]); sum += a[i]; } long long high = sum,low = 0,ans = 0,mid; while(high > low){ mid = (high+low)/2; if(work(mid)){ if(mid > ans) ans = mid; low = mid+1; } else high = mid; } printf("%lld/n",ans); long long pre = 0,idex = 1; for(int i = 1;i <= D; ++i){ pre /= 2; int start = idex; while(pre < ans) pre += a[idex++]; for(int j = start;j < idex; ++j) printf("%d/n",i); } for(int i = idex;i <= N; ++i) printf("%d/n",D); }

你可能感兴趣的:(TOJ 3584. Chocolate Eating 【二分+枚举】)