BZOJ 2016: [Usaco2010]Chocolate Eating( 二分答案 )

因为没注意到long long 就 TLE 了...

二分一下答案就Ok了..

------------------------------------------------------------------------------

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

#define rep( i , n ) for( int i = 0 ; i < n ; ++i )

#define clr( x , c ) memset( x , c , sizeof( x ) )

#define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )

using namespace std;

typedef long long ll;

const int maxn = 50000 + 5;

int n , d;

int h[ maxn ];

int ans[ maxn ];

bool jud( ll m ) {

int cur = 0;

ll p = 0;

Rep( i , d ) {

while( p < m ) {

if( ++cur > n ) return false;

p += h[ cur ];

}

p >>= 1;

}

return true;

}

void get( ll m ) {

int cur = 0;

ll p = 0;

Rep( i , d ) {

while( p < m )

p += h[ ++cur ] , ans[ cur ] = i;

p >>= 1;

}

for( int i = ++cur ; i <= n ; ++i ) ans[ i ] = d;

}

int main() {

freopen( "test.in" , "r" , stdin );

freopen( "test.out" , "w" , stdout );

ll L = 0 , R = 0;

cin >> n >> d;

Rep( i , n )

scanf( "%d" , h + i ) , R += h[ i ];

ll res;

while( L <= R ) {

ll m = ( L + R ) >> 1;

if( jud( m ) )

res = m , L = m + 1;

else

R = m - 1;

}

get( res );

cout << res << "\n";

Rep( i , n ) printf( "%d\n" , *( ans + i ) );

return 0;

}

------------------------------------------------------------------------------

2016: [Usaco2010]Chocolate Eating

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 235  Solved: 90
[Submit][Status][Discuss]

Description

贝西从大牛那里收到了N块巧克力。她不想把它们马上吃完,而是打算制定一个计划,

使得在接下来的D天里,她能够尽量地快乐。贝西的快乐指数可以用一个整数来衡量,一开始的时候是0,当她每天晚上睡觉的时候,快乐指数会减半(奇数时向下取整)。贝西把她的巧克力按照收到的时间排序,并坚持按照这个顺序来吃巧克力。当她吃掉第i块巧克力的时候,她的快乐指数会增加Hj。每天可以吃任意多块巧克力,如何帮助贝西合理安排,使得D天内她的最小快乐指数最大呢?

举个例子:假设一共有五块巧克力,贝西打算在五天时间内将它们吃完,每块巧克力提

供的快乐指数分别为10,40,13,22,7。则最好的方案如F:


天数


起床时快乐指数


食用的巧克力


就寝时快乐指数


1
    2
    3
    4
    5


0
    25
    12
    12
    17


10+ 40
 
    13
    22
    7


50
    25
    25
    34
    24

五天内的最小快乐指数为24,这是所有吃法中的最大值。

Input

第一行:两个用空格分开的整数:N和D,1≤N.D≤50000

第二行到第N+1行:第1+1行表示第i块巧克力提供的快乐指数Hj,1≤Hi≤1000000

Output

第一行:单个整数,表示贝西在接下来D天内的最小快乐指数的最大值

第二行到第N+1:在第i+l行有一个整数,代表贝西应该在哪一天吃掉第i块巧克力。

如果有多种吃法,则输出按照词典序排序后最靠后的方案

Sample Input

55
10
40
13
22
7

Sample Output

24
1
1
3
4
5

HINT

Source

Silver

时间: 2024-11-08 20:04:07

BZOJ 2016: [Usaco2010]Chocolate Eating( 二分答案 )的相关文章

BZOJ 2016: [Usaco2010]Chocolate Eating

题目 2016: [Usaco2010]Chocolate Eating Time Limit: 10 Sec  Memory Limit: 162 MB Description 贝西从大牛那里收到了N块巧克力.她不想把它们马上吃完,而是打算制定一个计划, 使得在接下来的D天里,她能够尽量地快乐.贝西的快乐指数可以用一个整数来衡量,一开始的时候是0,当她每天晚上睡觉的时候,快乐指数会减半(奇数时向下取整).贝西把她的巧克力按照收到的时间排序,并坚持按照这个顺序来吃巧克力.当她吃掉第i块巧克力的时

2016: [Usaco2010]Chocolate Eating

2016: [Usaco2010]Chocolate Eating Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 224  Solved: 87[Submit][Status][Discuss] Description 贝西从大牛那里收到了N块巧克力.她不想把它们马上吃完,而是打算制定一个计划, 使得在接下来的D天里,她能够尽量地快乐.贝西的快乐指数可以用一个整数来衡量,一开始的时候是0,当她每天晚上睡觉的时候,快乐指数会减半(奇数时向下取整).

bzoj2016[Usaco2010]Chocolate Eating

bzoj2016[Usaco2010]Chocolate Eating 题意: n块巧克力,每次吃可以增加ai点快乐,每天早晨睡觉起来快乐值会减半,求如何使d天睡觉前的最小快乐值最大.n,d≤50000 题解: 二分快乐值,每天不够就吃.注意如果最后一天有剩余巧克力,必须将其全部吃完. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define ll long long 5

[BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】

题目链接:BZOJ - 1816 题目分析 答案具有可以二分的性质,所以可以二分答案. 验证一个答案 x 是否可行,就累加一下各种牌相对于 x 还缺少的量,如果总和超过了 x 或 m ,就不可行. 因为,当使用的joker小于等于 x 时,才可以通过合适地安排顺序使得每组牌中至多有一张 joker . 代码 #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio>

BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流

题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连一条流量为k的边.两个人若互相喜欢则点1之间连边,不喜欢则点2之间连边 对于每个要验证的x值 将每个人的点1向源或汇连一条流量为x的边 然后二分答案跑最大流就可以 #include<cstdio> #include<cstring> #include<iostream> #

BZOJ 2097 Exercise 奶牛健美操 二分答案+树形DP+贪心

题目大意:给定一棵树,可以删掉k条边,求删掉后森林中所有树直径的最大值的最小值 最大值最小,典型的二分答案 此题我们二分树的直径,每次二分DFS一次,对于每个节点统计出所有子树删边后的dis,排序,贪心删掉最大的,直到最大的两个子树相加不会超过二分的答案为止 时间复杂度O(nlog^2n) 老子的二分居然写挂了...桑不起啊啊啊啊 #include<cstdio> #include<cstring> #include<iostream> #include<algo

[BZOJ 1816][Cqoi2010]扑克牌(二分答案)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1816 分析: 我先以为是道水题,但是要注意的是每套牌中Joker只能用1张的,所以就出现了可能目前每种牌的剩余牌数都够,但不一定不用Joker,然后就短路了…… 看了hzwer的blog顿时茅塞顿开,原来是二分…… 二分答案x,然后判定 判定的方法:注意每套牌顶多只有一个Joker,所以对于答案x,能用的Joker的最大数量是T=Min(x,m),然后枚举每种牌,将每种牌相对于答案x差的个数

BZOJ 3316 JC loves Mkk 二分答案+单调队列

题目大意:给定一个环,要求在这个环上截取长度为偶数且在[L,R]区间内的一段,要求平均值最大 看到环果断倍增 看到平均值最大果断二分答案 看到长度[L,R]果断单调队列 对数组维护一个前缀和,对前缀和维护单调递增的单调队列 每扫过一个数sum[i],将sum[i-L]加入单调队列,再把距离i超过R的点删掉 长度为偶数?对奇数位置和偶数位置分别维护一个单调队列即可 每次找到大于0的子串之后记录一下分母再退出就行了 #include <cstdio> #include <cstring>

BZOJ 1052 HAOI2007 覆盖问题 二分答案+DFS

题目大意:给定n个点,用三个边长相同的正方形覆盖所有点,要求正方形边界与坐标轴垂直,求正方形边长的最小值 最大值最小,很明显二分答案 但是验证是个问题 考虑只有三个正方形,故用一个最小矩形覆盖这三个正方形时至少有一个在角上 若有四个正方形该结论不成立 于是我们采用DFS的方式 每次用一个最小的矩形覆盖所有的点,枚举矩形的四个角 将正方形填进去 由于最大深度是3,所以时间上完全可以承受 #include<cstdio> #include<cstring> #include<io