二分: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 happiness
   1            0                10+40                  50
   2           25                 ---                   25
   3           12                  13                   25
   4           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;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值