Kick Veges' Ass
Description
有n个菜鸟站成一排,Jason要按顺序虐他们一下。虐第i个菜鸟需要花费掉A[i]点RP,现在Jason打算分k天虐完这些菜鸟。Jason每天的RP总数是固定的,为了使RP最低的时候不会过低导致杯具,他希望这k天中虐菜花费RP最多的一天,花费的RP尽量少。求Jason在花费RP最多那天花费了了多少RP。
Input
第一行两个正整数n,k。
第二行为此数列A[i]。
Output
一个数,为题目所求答案。
Sample Input
5 22 1 3 4 5
Sample Output
9
Hint
n ≤ 100,000, k ≤ n, ai ≤ 10^9
暑假第一次测验,师哥虐我们的题。以前没用二分做过题,真的!
“他希望这k天中虐菜花费RP最多的一天,花费的RP尽量少”说明,这题99%要用二分法了····师哥说,有时候别忽略了那1%的几率。总之,师哥给我们讲了,涨姿势了,代码:
#include<cstdio>
using namespace std;
int f[100010];
int n,k,sum=0,cnt;
int check(int rp){//测试最多RP时,需要几天虐完
cnt=1;
int x=rp;
for(int i=0;i<n;i++){
if(x>=f[i]) x-=f[i];
else{
cnt++;
x=rp-f[i];
}
}
if(cnt<k) return -1;
else if(cnt==k)return 0;
else return 1;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
scanf("%d",&f[i]);
sum+=f[i];
}
int left=0,right=sum,RP=(left+right)/2;
int ha=check(RP);
while(ha){//寻找答案大致位置
if(ha==-1) right=RP+1;
else left=RP-1;
RP=(right+left)/2;
ha=check(RP);
}
for(int i=left;i<=right;i++){//寻找答案具体位置
int ah=check(i);
if(!ah){
printf("%d\n",i);
break;
}
}
return 0;
}