题目:洛谷P2985。
题目大意:有n块巧克力要吃d天,并且只能按顺序吃。一块巧克力有一个开心值,吃了就能增加开心值。一个人初始开心值为0,且每天早上开心值变为原来的一半。问如何吃巧克力才能使开心值最小的一天开心值最大(每天都按吃完巧克力后计算),且需要输出方案。
解题思路:最大化最小值问题,用二分答案。
贪心地扫描,对于一个答案,如果开心值不到这个答案,就一直吃巧克力即可。
最后输出吃的方案时也用此种贪心法。
注意如果最后巧克力没有吃完,则在最后一天全部吃掉。
C++ Code:
#include<cstdio> #include<cctype> int n,d,a[50005]; long long l,r,ans; inline int readint(){ char c=getchar(); for(;!isdigit(c);c=getchar()); int d=0; for(;isdigit(c);c=getchar()) d=(d<<3)+(d<<1)+(c^‘0‘); return d; } bool ok(long long k){ long long kx=0; int qk=1; for(int i=1;i<=d;++i){ kx>>=1; while(kx<k&&qk<=n)kx+=a[qk++]; if(kx<k)return false; } return true; } void print(long long k){ long long kx=0; int qk=1; for(int i=1;i<=d;++i){ kx>>=1; while(kx<k&&qk<=n){ kx+=a[qk++]; printf("%d\n",i); } } while(qk<=n)printf("%d\n",d),++qk; } int main(){ n=readint(),d=readint(); for(int i=1;i<=n;++i)a[i]=readint(); l=0,r=50000000005LL,ans=0; while(l<=r){ long long mid=(l+r)>>1; if(ok(mid))l=(ans=mid)+1;else r=mid-1; } printf("%lld\n",ans); print(ans); return 0; }
时间: 2024-10-10 06:29:22