[USACO10FEB] 吃巧克力Chocolate Eating (二分答案)

题目链接

Solution

先直接二分答案,然后贪心判断,一旦少于答案就吃一块。
思路很简单,有一点细节。

  • 一天内可以不吃巧克力.
  • 注意处理最后时没吃完的全部在最后一天吃完.

Code

#include<bits/stdc++.h>
#define ll long long
#define N 50008
#define inf 0x3f3f3f3f3f3f3f
using namespace std;

void in(ll &x)
{
    char ch=getchar();ll f=1,w=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){w=w*10+ch-'0';ch=getchar();}
    x=f*w; return;
}

ll n,d,a[N],bl[N];

bool judge(ll st)
{
    ll now=0,res=d;
    for(int i=1;i<=n;i++)
    {
        if(now<st)
            {bl[i]=d-res+1;now+=a[i];}
        else {
			while(1){
            	now=now/2;
				if(now<st)break;
				res--;
			}
			res--; now+=a[i]; 
			bl[i]=d-res+1;
        }
    }
	while(1)
	{
		if(now<=st)break;
		res--; now=now/2;
	}
	if(res<1)return 1; 
	if(res==1&&now>=st)return 1;	
	return 0;
}

int main()
{
    in(n),in(d);
    for(int i=1;i<=n;i++) in(a[i]);
    ll l=0,r=inf;
	while(l<=r)
    {
        ll mid=(l+r)/2;
        if(judge(mid))l=mid+1;
        else r=mid-1;
    }
    cout<<l-1<<endl;
    judge(l-1);
    for(int i=1;i<=n;i++)
    {
        if(bl[i]==0||bl[i]>d)bl[i]=d;
        printf("%lld\n",bl[i]);
    }
    return 0;
}
posted @ 2019-07-18 20:09  Kevin_naticl  阅读(285)  评论(0编辑  收藏  举报