题解 | #Chocolate Eating# 这道题题解好少啊,写一篇吧
Chocolate Eating
https://ac.nowcoder.com/acm/problem/24724
题意:
贝西从bulls那里收到了N块巧克力。
她不想把它们马上吃完,而是打算制定一个计划,使得在接下来的D天里,使得每天的最小快乐值最大。
贝西的快乐指数可以用一个整数来衡量,一开始的时候是0,当她每天晚上睡觉的时候,快乐指数会减半(奇数时向下取整)。贝西把她的巧克力按照收到的时间排序,并坚持按照这个顺序来吃巧克力。当她吃掉第i块巧克力的时候,她的快乐指数会增加Hj。她那天的快乐值被认为是她吃完巧克力后的快乐水平。每天可以吃任意多块巧克力,如何帮助贝西合理安排,使得D天内她的最小快乐指数最大呢?解析
1.很明显,答案具有单调性,可以用 二分 + 检验的思路来做
2.二分出最小快乐值并检验即可
3.最后再进行一次检验,记录吃巧克力的天数坑点
1.巧克力全都要吃完
#include<iostream> #include<algorithm> #include<cmath> #include<cstdio> #include<vector> #include<string> using namespace std; int n,d; vector<int> seq; vector<int> record; bool check(long long int mid){ long long int sum = 0,index = 0; for(int i = 0;i < d; i++ ){ sum >>= 1; while(sum < mid){ if(index >= seq.size()) break; record[index] = i+1; sum = sum + seq[index++]; } if(sum < mid ) return false; } return true;; } int main(){ scanf("%d%d",&n,&d); seq.resize(n); record.resize(n); int maxx = -1; for(int i = 0;i < seq.size();i++) {cin>>seq[i];maxx = max(maxx,seq[i]);} long long int lift = 0, right = maxx,mid; while(lift <= right){ mid = lift + ((right - lift ) >> 1); if(check(mid)) lift = mid + 1; else right = mid - 1 ; } check(right); cout<<right<<endl; for(int i = 0;i < record.size();i++){ if(record[i] == 0) cout<<d; else cout<<record[i]<<endl; } return 0; }