题面
Monocarp has identical boxes. The weight of each box is , and the durability of each box is .
To save space, Monocarp wants to build several “towers” of boxes by stacking them on top of each other. Each tower will consist of a positive (greater than ) integer number of boxes stacked on top of each other. To ensure that no box breaks, the following condition must be met:
- for each box, the total weight of all boxes above it must not exceed the durability of that box.
Help Monocarp calculate the minimum number of towers he can achieve, given that each of the boxes must be used.
Input
The first line contains a single integer () — the number of test cases.
Each test case consists of a single line containing three integers ().
Output
For each test case, print one integer — the minimum number of towers.
思路
关键转化
所有盒子完全相同,每个盒子的重量为 耐久为 , 因此任意一座塔只和它的高度有关
设某一座塔从上到下共有 个盒子
第 个盒子上方有 个盒子,因而它承受的上方总重量为
因为 越大,上方盒子越多,承受重量越大;所以在同一座塔中最危险的是最底下的盒子
最底下的盒子上方共有 个盒子,承受重量为
题目要求对每个盒子都满足:上方总重量不超过耐久 由于最底下盒子的承受重量最大,只要最底下不破,上面的盒子承受重量更小,一定也不破
因此一座塔可行当且仅当
对不等式进行变形
令单座塔允许的最大高度为
则每座塔最多放 个盒子
最小塔数
现在问题等价为 将 个盒子分成若干组,每组大小在 之间,使得组数最少
显然每座塔最多放 个盒子,所以塔的数量至少为
同时这个下界一定能达到,所以采用贪心将盒子尽量装满 前若干座塔各放 个盒子,最后一座塔放剩余的 个盒子,若余数为 则不存在最后一座塔
因为最后一座塔的高度也不超过 所以一定满足耐久条件
因此最小塔数就是:
为了只用整数计算,可以把上式写成
代码:
#include <bits/stdc++.h>
using namespace std;
int main() { int t; cin >> t; while (t --) { long long n, m, d; cin >> n >> m >> d;
long long H = d / m + 1; long long ans = (n + H - 1) / H;
cout << ans << '\n'; }}