求最小幸福值的最大值,本题中只需要以答案入手去二分答案即可。
至于如何验证:从第一天开始遍历,如果幸福值小于给定的最小幸福值那么就吃巧克力就完了。
至于如何验证:从第一天开始遍历,如果幸福值小于给定的最小幸福值那么就吃巧克力就完了。
看最后是巧克力被先吃完,还是能够满足贝西每天的幸福值需要。
需要注意的是在记录记录每天吃巧克力的方案的时候前提是需要验证通过。因为最后结果有可能是从不通过的右边移动到左边然后退出循环的。
坑点:这个坑点想半天也没想出来,最后看题解说是巧克力必须吃完。这个只能靠猜,真的服了。。。。
//求最小幸福值的最大值,本题中只需要以答案入手去二分答案即可。
//至于如何验证:从第一天开始遍历,如果幸福值小于给定的最小幸福值那么就吃巧克力就完了。
//看最后是巧克力被先吃完,还是能够满足贝西每天的幸福值需要。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 50000+10;
ll N, D;
ll h[maxn];
//记录每天吃巧克力的方案
ll ans[maxn];
ll cnt[maxn];
bool yanz(ll mid) {
memset(cnt, 0, sizeof(cnt));
ll j = 0;
ll hap_score = 0;
for (int i=0;i<D;i++) {
while (hap_score<mid&&j<N) {
cnt[j] = i+1;
hap_score += h[j++];
}
if (hap_score<mid) return false;
hap_score /= 2;
}
memcpy(ans, cnt, sizeof(cnt));
while (j<N) {
ans[j++] = D;
}
return true;
}
int main() {
scanf("%lld %lld", &N, &D);
for (int i=0;i<N;i++) {
scanf("%lld", h+i);
}
ll l = 0, r = 1000000ll*50000;
while (l<r) {
// cout<<l<<" "<<r<<endl;
ll mid = (l+r+1)/2;
if (yanz(mid)) l = mid;
else r = mid-1;
}
cout<<l<<endl;
for (int i=0;i<N;i++) {
if (ans[i])
printf("%lld\n", ans[i]);
}
return 0;
}

京公网安备 11010502036488号