B. Box Fitting
给定一些高度为1,长度为2的幂次的砖块,要将所有砖块堆叠在长为W的容器里,使得堆起来的高度最小,求最小高度。
做法:
对于当前层的铺砖块,从最高位往最低位遍历,如果这一位有砖块,且这一层还铺的下这块砖,那就铺上这块砖。
就像倍增求LCA一样,从logn往0遍历,能跳就跳。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5, mod = 1000003;
int a[N];
int f[35];
int ws(int n)
{
int cnt = -1;
while(n)
{
cnt++;
n >>= 1;
}
f[cnt]++;
return cnt;
}
signed main ()
{
// cout << ws(8);
int tt;
cin >> tt;
while(tt--)
{
int n, w;
cin >> n >> w;
int start = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
int ret = ws(a[i]);
start = max(start, ret);
}
int ans = 0;
while(1){
int sum = w;
for (int i = start; i >= 0; i--)
{
while(f[i] && sum >= (1 << i)) {
f[i]--;
sum -= (1 << i);
}
}
if (sum == w) break;
ans++;
}
printf("%lld\n", ans);
memset(f, 0, sizeof(f));
}
return 0;
}