SDNU 1331.Kick Veges' Ass【SDNU2015暑期集训队测验I】【二分法】【8月3】

本文介绍了一个关于如何合理分配有限资源的问题,即如何将一系列数值分配到固定数量的组中,使得最大的组内数值总和最小。文章通过一个具体的例子来解释问题背景,并提供了一段使用二分查找法解决该问题的C++代码。

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值