時隔一個多月,oj關(guān)閉之后,我終于來補(bǔ)題了...
題目鏈接:
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);
模擬的話,是先來一個機(jī)器人,遍歷貨物,如果機(jī)器人抬得起貨就抬貨,可抬貨數(shù)目-=該項貨數(shù);抬不起貨就換一個新的機(jī)器人(抬貨),同時機(jī)器人數(shù)目加1,如果新的機(jī)器人也抬不起貨直接return 0.遍歷完之后看所用機(jī)器人數(shù)目有沒有超過m,返回。
因為沒有學(xué)學(xué)長的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) //機(jī)器人:我能抬的貨我就抬
{
cur-=box[i];
//printf("cur(我現(xiàn)在可以抬的)is %d,box[%d] is %d\n",cur,i,box[i]);
}
else //機(jī)器人:我抬不起的貨我就喊新機(jī)器人抬
{
num++;
//printf("加機(jī)器人 \n");
cur=size;
if(box[i]<=cur) //新機(jī)器人抬貨
cur-=box[i];
else //碰見了新機(jī)器人也抬不起的貨了..
{
return 0;
}
}
}
//抬貨結(jié)束
//printf("num is %d\n",num);
if(num<=m)
return 1;
else
return 0;
}
int main()
{
int sum=0,mid; //不要重復(fù)定義!??!
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);
}