题目
贝西收到了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.没关注到巧克力没吃完的情况,有想到,但后面没怎么管,看题解才发现真有这种情况