写题的时候最开始想的是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();
}
}
京公网安备 11010502036488号