晾衣服:n件衣服各含a_i水分,自然干一分钟一单位,放烘干机一分钟k单位,一次只能晒一件。求最短时间。
二分的应用题
取C(mid) := 能在mid分钟内处理完,然后二分即可。
这里有两个很好玩的陷阱
①每分钟烘干k单位的水,于是我就想当然地除k向上取整了((a_i – mid) / k)。其实应该除以k-1,列个详细的算式:
设需要用x分钟的机器,那么自然风干需要mid – x分钟,x和mid需要满足:
k*x + (mid – x) >= a_i,即 x >= (a_i – mid) / (k – 1)。
②当k=1的时候,很显然会发生除零错误,需要特殊处理。
以上是百度来的大佬的解法,神奇的二分。
判断需要使用洗衣机的临界值,也就是使用洗衣机和不使用洗衣机的大约同时结束。
相当于排序的取中点问题。二分查找。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int a[100005];
int k;
int n;
bool judge(int mid)
{long long sum=0;//注意数据范围for(int i=0;i<n;i++){if(a[i]>mid)sum+=(a[i]-mid+k-2)/(k-1);//向上取整}if(sum<=mid) return true;//判断中点是取大了还是取小了elsereturn false;
}
int main()
{while(scanf("%d",&n)!=EOF){memset(a,0,sizeof(a));int i,j;int max=0; for(i=0;i<n;i++){scanf("%d",&a[i]);if(max<a[i])max=a[i];}scanf("%d",&k);if(k==1){printf("%d\n",max);break;}int right=max;int left=0;int mid;while(right-left>1) {mid=(right+left)/2;if(judge(mid))right=mid;elseleft=mid;}printf("%d\n",right);}}