​D - Fill The Bag​

参考:​​Educational Codeforces Round 82 A~E 题解​

因为这道题的​​a[i]​​是2的幂次方,相当于是提示了我们需要用位运算来进行解决。

​a[i]​​​相当于二进制中的每一位,我们要做的是把​​a[i]​​​填进 n 的每一位中,一个​​a[i]​​只能填一位。

低位的数字可以填高位,而高位的数字则需要进行拆分才能填低位,所以遍历应该从低位开始。

每填完一个位置,可以将该位置剩下的数放入下一个位置(除2即可)

// Created by CAD on 2020/2/12.
#include <bits/stdc++.h>

#define mst(name, value) memset(name,value,sizeof(name))
#define ll long long
using namespace std;

const int maxn=1e5+5;
int a[maxn];
int cnt[65];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;cin>>t;
while(t--){
ll n,m,sum=0;cin>>n>>m;
mst(cnt,0);
for(int i=1;i<=m;++i)
cin>>a[i],sum+=a[i],cnt[__builtin_ctz(a[i])]++;
if(sum<n){
cout<<-1<<'\n';
continue;
}
ll ans=0;
for(int i=0;i<=60;++i){
if((n>>i)&1){
int j=i;
while(!cnt[j]) ++j;
while(i!=j) cnt[j]--,cnt[j-1]+=2,ans++,j--;
cnt[i]--;
}
cnt[i+1]+=cnt[i]/2;
}
cout<<ans<<'\n';
}
return 0;
}

CAD加油!欢迎跟我一起讨论学习算法,