Fill The Bag

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;
}
posted @ 2020-02-13 15:26  caoanda  阅读(165)  评论(0编辑  收藏  举报