题意:我要把一些衣服弄干,已知每件衣服的含水量,如果让他们自然干,没小时少1单位水,如果用烘干机,每小时少k单位水,但烘干机没小时只能放一件衣服。
思路:我一开始是用贪心做的,TLE(每次取含水量最多的衣服放进烘干机一小时,再取含水量最多的衣服,重复操作直到含水量最多的衣服含水量为0)。看了网上的题解才知道,应该用二分法找最短时间。其中在烘干时,每小时减少的水量中k-1视为烘干机的效果,仍然有1为自然干。则对于含水量大于 t 的衣服,其中t为自然干,烘干的部分为a[i] - t,是烘干机作用 ( a[i] - t + (k - 1) - 1 ) / (k - 1) 小时的效果(a / b取上界等于(a + b - 1) / b)。用sum记录烘干机作用时间之和,最短时间 t 应满足, t >= sum。所以用二分法求第一个满足该条件的 t 值(二分法取下界)。
另外要注意数据范围
unsigned int 和 unsigned long 约为 0~4* 10 ^ 9
int 和 long 绝对值约为 2 * 10 ^ 9
long long 绝对值约为 9* 10 ^ 18
unsigned long long的最大值:约为 0 ~ 18 * 10 ^ 18
此题应用long long
#include
#include
using namespace std;
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif
int n, i;
long long l, r, mid, sum, ans;
long long a[100010], k;
while(scanf("%d", &n) != EOF)
{
for(i = 0; i < n; i++)
{
scanf("%lld", &a[i]);
}
scanf("%lld", &k);
sort(a, a + n);
if(k == 1)
{
printf("%lld\n", a[n -1]);
continue;
}
l = 1; r = a[n - 1]; ans = 0;
while(l <= r)
{
sum = 0;
mid = (l + r) / 2;
for(int i = n - 1; i >= 0; i-- )
{ if(a[i] > mid)
{
sum += (a[i] - mid + k - 2) / (k - 1);
}
else break;
}
//注意二分查找去下界的写法
if(sum <= mid)
{
r = mid - 1;
}
else
{
l = mid + 1;
}
}
printf("%lld\n", l);
}
return 0;
}