开 始 老 是 贪 心 的 想 要 用 掉 大 的 数 字 开始老是贪心的想要用掉大的数字 开始老是贪心的想要用掉大的数字

但 是 这 样 并 不 好 处 理 , 不 如 没 用 掉 的 数 不 知 道 是 否 要 往 下 分 解 但是这样并不好处理,不如没用掉的数不知道是否要往下分解 但是这样并不好处理,不如没用掉的数不知道是否要往下分解

假如优先用掉小的数字呢?

比 如 我 们 从 n 的 二 进 制 最 低 位 i 开 始 填 充 比如我们从n的二进制最低位i开始填充 比如我们从n的二进制最低位i开始填充

那 么 我 们 肯 定 去 找 一 个 大 于 ( 1 < < ( i − 1 ) ) 且 尽 量 小 的 数 那么我们肯定去找一个大于(1<<(i-1))且尽量小的数 那么我们肯定去找一个大于(1<<(i−1))且尽量小的数

一 直 分 解 成 第 i 位 一直分解成第i位 一直分解成第i位

然 后 往 下 继 续 看 n 的 下 一 位 二 进 制 然后往下继续看n的下一位二进制 然后往下继续看n的下一位二进制

但 是 注 意 1 和 1 可 以 合 并 成 2 , 2 和 2 可 以 合 并 成 4 但是注意1和1可以合并成2,2和2可以合并成4 但是注意1和1可以合并成2,2和2可以合并成4

也 就 是 说 , 如 果 当 前 这 一 位 二 进 制 填 充 完 了 , 那 么 剩 下 没 用 的 就 合 并 成 下 一 位 二 进 制 也就是说,如果当前这一位二进制填充完了,那么剩下没用的就合并成下一位二进制 也就是说,如果当前这一位二进制填充完了,那么剩下没用的就合并成下一位二进制

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,sumn;
ll cnt[67],m,t;
map<ll,ll>tu;
int main()
{
for(ll i=1,j=1;i<=63;i++)
{
tu[j]=i;
j*=2;
}
cin>>t;
while(t--)
{
cin>>n>>m;
sumn=0;
memset(cnt,0,sizeof(cnt));
for(int i=1,x;i<=m;i++)
{
cin>>x;
sumn+=x;
cnt[ tu[x]-1 ]++;
}
if(sumn<n){
puts("-1");continue;
}
ll ans=0;
for(ll i=0,j;i<=62;i++)
{
if( n&(1ll<<i) )
{
j=i;
while( !cnt[j] ) j++;
while( j!=i )
{
cnt[j]--;
cnt[j-1]+=2;
ans++;j--;
}
cnt[i]--;
}
cnt[i+1]+=cnt[i]/2;
}
printf("%lld\n",ans);
}
}