Description
贝西从大牛那里收到了
N
块巧克力。她不想把它们马上吃完,而是打算制定一个计划,使得在接下来的
举个例子:假设一共有五块巧克力,贝西打算在五天时间内将它们吃完,每块巧克力提供的快乐指数分别为10,40,13,22,7。则最好的方案如下:
天数 | 起床时快乐指数 | 食用的巧克力 | 就寝时快乐指数 |
---|---|---|---|
1 | 0 | 10+40 | 50 |
2 | 25 | 25 | |
3 | 12 | 13 | 25 |
4 | 12 | 22 | 34 |
5 | 17 | 7 | 24 |
五天内的最小快乐指数为24,这是所有吃法中的最大值。
Input
第一行:两个用空格分开的整数:
第二行到第
N+1
行:第
i+1
行表示第
i
块巧克力提供的快乐指数
Output
第一行:单个整数,表示贝西在接下来
D
天内的最小快乐指数的最大值。
第二行到第
如果有多种吃法,则输出按照词典序排序后最靠后的方案。
Sample Input
55
10
40
13
22
7
Sample Output
24
1
1
3
4
5
HINT
Source
Silver
方法
二分答案,每次想办法维持当前这个答案,如果维持不了那么说明不可以达到,否则则可以。
代码
#include <cstdio>
const long long maxn=50000;
long long n,d,h[maxn+10],v[maxn+10],left,right,ans;
long long check(long long lim,long long mode)
{
long long en=0,now=0;
for(long long i=1; i<=d; i++)
{
en/=2;
while(en<lim)
{
now++;
if(now>n)
{
return 0;
}
en+=h[now];
if(mode)
{
v[now]=i;
}
}
}
return 1;
}
int main()
{
scanf("%lld%lld",&n,&d);
for(long long i=1; i<=n; i++)
{
scanf("%lld",&h[i]);
right+=h[i];
}
while(left<=right)
{
long long mid=(left+right)>>1;
if(check(mid,0))
{
ans=mid;
left=mid+1;
}
else
{
right=mid-1;
}
}
check(ans,1);
printf("%lld\n",ans);
for(long long i=1; i<=n; i++)
{
if(v[i])
{
printf("%lld\n",v[i]);
}
else
{
printf("%lld\n",d);
}
}
return 0;
}