写题的时候最开始想的是bitset写一个背包,但是这道题里bitset开不下
然后想到了CF上写过的这道题
CF1498B
题意是说给定一个容量为w的背包,每个物件的体积都是2的幂次方,求最少能用多少个背包把所有物件装下
迭代N次,每次迭代25位,选出一个可选的最大的物块。这样每个背包里容量都是尽可能大的。
那么对于每日一题这道题,可以考虑每次背包装满时,背包容量是否达到2^30,如果达到了回溯一下输出序列即可
#include <bits/stdc++.h> #define ios ios::sync_with_stdio(false), cin.tie(0); #define et cout<<endl; #define YES cout << "YES" << endl; #define NO cout << "NO" << endl; #define INF 0x3f3f3f3f; using namespace std; typedef pair<int, int> PII; typedef long long ll; typedef unsigned long long ull; inline int read() { int x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();} while (isdigit(ch)){x=x*10+ch-48;ch=getchar();} return x*f; } const int N = 2e5+5; const int M = 2e5+5; const int mod = 1e9+7; int t, n, k; int cnt[35]; int g[N]; void solve() { memset(cnt, 0, sizeof cnt); int n, w = 1 << 30; cin >> n; for(int i = 1; i <= n; i ++) { int x; cin >> x; g[i] = x; cnt[x] ++; } int left_size = w; vector<int> v; for(int i = 1; i <= n; i ++) { int largest = -1; for(int i = 29; ~i; i --) { if(cnt[i] && left_size >= (1 << i)) { largest = i; break; } } if(largest == -1) { v.clear(); left_size = w; for(int i = 29; ~i; i --) { if(cnt[i] && left_size >= (1 << i)) { largest = i; break; } } } cnt[largest] --; left_size -= (1 << largest); v.push_back(largest); if(left_size == 0) { break; } } if(left_size != 0) { cout << "impossible" << endl; return; } unordered_map<int, int> mp; for(auto i: v) { mp[i] ++; } for(int i = 1; i <= n; i ++) { if(mp[g[i]]) { cout << 1; mp[g[i]] --; } else cout << 0; } cout << endl; } int main() { ios bool multi = 1; // 0 for single and 1 for multi if(multi) cin >> t; else t = 1; while(t--) { solve(); } }