时隔一个多月,oj关闭之后,我终于来补题了...
题目链接:
https://pintia.cn/problem-sets/1098080354122080256/problems/1098502465433116672
解题思路:
二分+模拟
判断一下货物的取值范围是1~sum,然后开始二分了
二分的话,
while(r<l)
{
int mid=(r+l)/2;
if(check(mid)==1) //这里模拟
r=mid;
else
l=mid+1;
}
printf("%d",r);
模拟的话,是先来一个机器人,遍历货物,如果机器人抬得起货就抬货,可抬货数目-=该项货数;抬不起货就换一个新的机器人(抬货),同时机器人数目加1,如果新的机器人也抬不起货直接return 0.遍历完之后看所用机器人数目有没有超过m,返回。
因为没有学学长的fropen所以只是过了样例不知道ac没有的代码:
#include<stdio.h>
int box[10005],n,m;
int check(int size)
{
int cur=size,num=1;
for(int i=1;i<=n;i++)
{
if(box[i]<=cur) //机器人:我能抬的货我就抬
{
cur-=box[i];
//printf("cur(我现在可以抬的)is %d,box[%d] is %d\n",cur,i,box[i]);
}
else //机器人:我抬不起的货我就喊新机器人抬
{
num++;
//printf("加机器人 \n");
cur=size;
if(box[i]<=cur) //新机器人抬货
cur-=box[i];
else //碰见了新机器人也抬不起的货了..
{
return 0;
}
}
}
//抬货结束
//printf("num is %d\n",num);
if(num<=m)
return 1;
else
return 0;
}
int main()
{
int sum=0,mid; //不要重复定义!!!
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) //此处不建议用0~n-1,因为后面left不好取0
{
scanf("%d",&box[i]);
sum+=box[i];
}
//这里明确一下,货物的取值范围是(sum/m~sum)
int l=1,r=sum;
//printf("l is %d,r is %d\n",l,r);
while(l<r)
{
mid=(r+l)/2; //取中值点
//printf("l is %d,mid is %d,r is %d\n",l,mid,r);
if(check(mid))
{
r=mid;
//printf("%d 过多了,我们从左边到中间\n",mid);
}
else
{
l=mid+1;
//printf("%d 是太少了的,我们从中间到右边\n",mid);
}
}
printf("%d",r);
}