/*
translation:
要使得一排衣服晾干,自然风干每分钟蒸发1单位的水分。用烘干机的话每分钟蒸发k单位的水分。求把所有衣物晾干的话至少需要多长时间?
solution:
二分查找最小可行解
首先二分枚举最短的时间mid。然后是判断该时间是否可行。可以发现对于水分单位量小于mid的衣服。只需要待其自然风干即可。
而对于a[i]>mid的衣物来说,要使得能够在mid时间内完成衣物的烘干。就要满足方程:a[i]-t*k <= x-t(t为使用烘干机的时间)
解得t >= (a[i] - x) / (k-1).注意这时候要用ceil函数向上取整。
note:
1:这道题的二分循环次数如果设成100将超时。设置成50就可以。或者用pr - pl > 1来终止循环也可以
2:注意k等于1的时候t >= (a[i] - x) / (k-1)的计算将出现错误。所以要对于k==1的情况单独处理
#:这道题怎么判断所枚举的时间是否可行没想出来
date:
2016.11.2
*/
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 100000 + 10;
const int INF = 1e9 + 10;
typedef long long ll;
ll a[maxn], n, k;
bool check(ll x) //x的时间内能否使得所有的衣服晾干
{
ll res = 0;
for(int i = 0; i < n; i++){
if(a[i] > x){
res += ceil((a[i] - x) * 1.0 / (k - 1));
if(res > x) return false;
}
}
return true;
}
int main()
{
//freopen("in.txt", "r", stdin);
while(~scanf("%lld", &n)){
ll pl = 0, pr = 0;
for(int i = 0; (ll)i < n; i++) scanf("%lld", &a[i]), pr += a[i];
scanf("%lld", &k);
if(k == 1){
ll ans = -INF;
for(int i = 0; i < n; i++) ans = max(ans, a[i]);
printf("%d\n", ans); continue;
}
ll mid;
while(pr - pl > 1){
mid = (pl + pr) / 2;
if(check(mid)) pr = mid;
else pl = mid;
}
printf("%lld\n", pr);
}
return 0;
}
poj3104(二分判断可行性)
最新推荐文章于 2021-10-05 20:30:55 发布