本文主要是介绍二分:chocolate eating,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目描述:链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
Bessie has received N (1 <= N <= 50,000) chocolates from the bulls, but doesn't want to eat them too quickly, so she wants to plan out her chocolate eating schedule for the next D (1 <= D <= 50,000) days in order to maximize her minimum happiness level over the set of those days.
Bessie's happiness level is an integer that starts at 0 and halves (rounding down if necessary) over night as she sleeps. However, when she eats chocolate i, her happiness level increases by integer HiH_iHi (1 <= HiH_iHi <= 1,000,000). If she eats chocolates on a day, her happiness for that day is considered the happiness level after she eats the chocolates. Bessie insists that she eat the chocolates in the order that she received them.
If more than one optimal solution exists, print any one of them.
Consider a sequence of 5 chocolates to be eaten over a period of 5 days; they respectively bring happiness (10, 40, 13, 22, 7).
If Bessie eats the first chocolate (10 happiness) on the first day and then waits to eat the others, her happiness level is 10 after the first day.
Here is the complete schedule which turns out to maximize her minimum happiness:Day Wakeup happiness Happiness from eating Bedtime happiness1 0 10+40 502 25 --- 253 12 13 254 12 22 34 5 17 7 24 The minimum bedtime happiness is 24, which turns out to be the best Bessie can do.
输入描述:
* Line 1: Two space separated integers: N and D * Lines 2..N+1: Line i+1 contains a single integer: HiH_iHi
输出描述:
* Line 1: A single integer, the highest Bessie's minimum happiness can be over the next D days * Lines 2..N+1: Line i+1 contains an integer that is the day on which Bessie eats chocolate i
示例1
输入
5 5 10 40 13 22 7
输出
24 1 1 3 4 5
大意描述:她有n块巧克力,要在k天内吃完,并且吃的顺序已经给定,每块巧克力可以给她带来一定的幸福值,而且每天晚上她的幸福值会减半,求她的最小幸福值的最大值,并给出每块巧克力是在第几天被吃掉的。
解析:
求最小值的最大值,这是典型的二分思路,那么我们可以直接对答案进行二分,对于每次判断,使用一个while循环,即当sum(累计幸福值)还小于所二分的结果时,就不断喂她吃巧克力,直到她的sum>=二分结果。对于巧克力被吃的记录,可以另开应该数组,当吃掉它的时候,就将它记录,这并不是难事,关键就在于判断应该怎么写了。
但是,还有几个小点要注意(我为此wa了好几次。。。)。 首先是关于判断函数该在哪些情况下返回false:所有巧克力都吃完了,但没有撑到最后一天,或者撑到了最后一天,但最后一天的幸福值没有达到要求,那么就要返回false。 其次,当巧克力过多,即吃到最后,幸福值也够了的时候,巧克力还有剩,那么对于剩下的巧克力,我们应该在最后一天全部吃掉,因为题目要求输出的是“每块巧克力是在第几天被吃掉的。” 以及,开二分的时候,上界要取够,可以用一个ans求出所有巧克力幸福值的总和作为上界,也可以直接long long 一个1e15; 最后,当二分循环已经求出答案时,我们应该在循环外再进行一次判断,因为我们的判断函数,除了判断的功能之外,还要记录每块巧克力被吃的日子,在最后重新进行一次这个操作,即对答案再记录一次每块巧克力被吃的日子,那么就可以保证其正确性,因为在二分循环中进行的若干次操作,会对记录的数组进行错误篡改。
上代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,d,mas[50010],r=1e16,l=0,k[50010];
bool judge(ll x){//每天最小开心值为x; //memset(k,0,sizeof(k));ll sum=0;ll zhen=1,i=1;for(;i<=d;++i){//d天 while(sum<x&&zhen<=n){k[zhen]=i;sum+=mas[zhen++];}if(sum<x) return false;sum>>=1;}while(zhen<=n) k[zhen++]=d; //点1.。。//if(i<d) return false;return true;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n;cin>>d;//n块巧克力,k天吃完; for(int i=1;i<=n;++i) cin>>mas[i];while(l<=r){ll mid=(l+r)>>1;if(judge(mid)) l=mid+1;else r=mid-1;}cout<<l-1<<endl;judge(l-1);//点2.。。。。for(int i=1;i<=n;++i) cout<<k[i]<<endl;return 0;
}
这篇关于二分:chocolate eating的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!