网课:第四章二分、三分、01分数规划---[USACO 2010 Feb S]Chocolate Eating

题目

贝西收到了N(1 <= N <= 50,000)块巧克力,但她不想吃得太快,因此她想为接下来的D(1 <= D <= 50,000)天制定巧克力食用计划,以便在那些天中最大化她的最低幸福水平。 贝西的幸福水平是一个整数,起始值为0,在夜间睡觉时减半(如果必要的话向下取整)。然而,当她吃掉第i块巧克力时,她的幸福水平增加了整数 Hi (1 <= Hi <= 1,000,000)。如果她在一天中吃了巧克力,她当天的幸福被认为是她吃巧克力后的幸福水平。贝西坚持按照她收到的顺序吃巧克力。 如果存在多个最优解,打印其中任何一个。 将一系列5块巧克力视为在5天内食用的一段时间; 它们分别带来幸福(10、40、13、22、7)。 如果贝西在第一天吃第一块巧克力(10幸福)然后等待吃其他的,那么她在第一天后的幸福水平是10。


 

输入

第1行:两个用空格分隔的整数:N 和 D

第2行到第N+1行:每行包含一个整数: Hi

5 5 
10 
40 
13 
22 
7

输出

第1行:一个整数,贝西在接下来的D天内最高的最小幸福水平

第2行到第N+1行:每行包含一个整数,表示贝西吃掉巧克力i的日期

24
1
1
3
4
5

做法

最小值最大,典型的二分答案。

#include<bits/stdc++.h>
using namespace std;
int n,d;
int isleft(long long num,vector<int> &v){
    long long res=0;
    int cnt=0;
    for(int i=1;i<=d;i++){
        while(res<num&&cnt<n){
            res+=v[cnt++];
        }
        if(res<num) return 0;
        res/=2;
        
    }
    return 1;
}
int main(){
    scanf("%d%d",&n,&d);
    vector<int> v(n);//开心值
    vector<int> g(n);
    long long sum=0;//总开心值
    for(int i=0;i<n;i++){
        scanf("%d",&v[i]);
        sum+=v[i];
    }
    long long l=-1,r=sum+1;
    while(l+1<r){
        long long mid=l+(r-l)/2;
        if(isleft(mid,v)) l=mid;
        else r=mid;
    }
    long long res=0;
    int cnt=0;
    cout<<l<<endl;
    for(int i=1;i<=d;i++){
        while(res<l&&cnt<n){
            g[cnt]=i;
            res+=v[cnt++];
        }
        res/=2;
        
    }
    for(int i=0;i<n;i++) {
        if(g[i])cout<<g[i]<<endl;
        else cout<<d<<endl;//没吃完
    }
    
}

wa的原因

1.弄错了题意,isleft函数的条件写错了

2.没开long long

3.没关注到巧克力没吃完的情况,有想到,但后面没怎么管,看题解才发现真有这种情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值