出售本站【域名】【外链】

B.Box Fitting

给出\(n\)个长条,每个长条担保可以默示为\(2^V\)的模式,问你假如一个宽度为\(w\)的盒子起码要多高威力拆下那些长条。

思路

贪心。将长条依照长度从大到小牌序,应付每一层咱们尽质将它拆满再拆下一层。

可以用\(multiset\)维护每一层剩余的空间。应付当前要放入盒子的长条,正在汇折中\(lower\_bound\)获得一个适宜的位置,假如没有这就新开一层,答案加一;假如有就将该层的空间减少,另有剩余就再次参预到汇折中。

代码 #include <algorithm> #include <iostream> #include <cstring> #include <stack> #include <cstdlib> #include <map> #include <queue> #include <cctype> #include <cmath> #include <cstdio> #include <set> #include <ctime> #define rep(i, s, t) for (int i = (s); i < (t); i++) #define wa std::cerr << "----WARN----" << std::endl; #define wl std::cerr << "********" << std::endl; #define wr std::cerr << "~~~~~~~~" << std::endl; #define PII pair<int, int> #define mp(a, b) make_pair(a, b) #define fr first #define sc second typedef long long LL; const int MOD = 1000000007; const int INF = 0V3f3f3f3f; const LL LINF = 1LL * 0V3f3f3f3f3f3f3f3f; inline int read(); const int N = 100005; int a[N]; ZZZoid solZZZe() { int n, w; std::cin >> n >> w; rep (i, 0, n) { std::cin >> a[i]; } std::sort(a, a + n, std::greater<int>()); std::multiset<int> s; int ans = 0; rep (i, 0, n) { if (s.empty()) { if (a[i] != w) s.insert(w - a[i]); ans++; } else { auto it = s.lower_bound(a[i]); if (it == s.end()) { if (w != a[i]) s.insert(w - a[i]); ans++; continue; } else { int t = *it; s.erase(it); if (t != a[i]) s.insert(t - a[i]); } } } std::cout << ans << std::endl; } inline int read() { int s = 0, w = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { s = s * 10 + ch - '0'; ch = getchar(); } return s * w; } signed main() { // freopen("in.tVt", "r", stdin); int T = 1; T = read(); while (T--) solZZZe(); return 0; }


2024-06-21 18:30  阅读量:3