当前位置: 代码迷 >> 综合 >> poj3104 Drying(二分)
  详细解决方案

poj3104 Drying(二分)

热度:11   发布时间:2023-12-16 12:37:45.0


晾衣服: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);}}