codeforces1303D Fill The Bag 二进制应用and贪心
Posted aya-uchida
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces1303D Fill The Bag 二进制应用and贪心相关的知识,希望对你有一定的参考价值。
网址:https://codeforces.com/contest/1303/problem/D
题意:
给出空间为$n$的容器和$m$个盒子。这些盒子的大小都是$2^k$的正整数,且可以减半,问使得容器刚好被盒子装满的最小减半次数是多少,如果不可能刚好装满,输出$-1$。
题解:
统计$2^k$大小的盒子有多少个,然后从低位到高位贪心,因为高位的一定需要减半才能到低位,所以就会增加减半次数,而低位变成高位却无影响。对于某一位$i$,如果它是$1$,那么对于这一位,如果已经没有了大小是$2^i$的盒子,则需要从$i+1$位的减半一次,$i+1$位上的盒子数是$-1$也没有关系,因为它会从$(i+1)+1$位拿过来,类似于减法退位。如果有剩下的,就直接合并到$i+1$位,最后输出减半次数就是答案。
AC代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; int cnt[65]; int solve() { memset(cnt, 0, sizeof(cnt)); ll n, sum = 0; int m, a; scanf("%lld%d", &n, &m); for (int i = 1; i <= m; ++i) { scanf("%d", &a); sum += a; int tmp = 0; while (a > 1) ++tmp, a >>= 1; ++cnt[tmp]; } if (sum < n) return printf("-1 "), 0; int ans = 0; for (int i = 0; i <= 63; ++i) { int x = (n >> i) & 1; cnt[i] -= x; if (cnt[i] >= 2) cnt[i + 1] += cnt[i] / 2, cnt[i] -= (cnt[i] / 2) * 2; if (cnt[i] < 0) --cnt[i + 1], ++ans; } return printf("%d ", ans), 0; } int main() { int t; scanf("%d", &t); while (t--) solve(); return 0; }
以上是关于codeforces1303D Fill The Bag 二进制应用and贪心的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #538 (Div. 2) D. Flood Fill 区间dp || LPS (最长回文序列)
解决:Error: Aesthetics must be either length 1 or the same as the data : fill