Fill The Bag
You have a bag of size n. Also you have m boxes. The size of i-th box is ai, where each ai is an integer non-negative power of two.
You can divide boxes into two parts of equal size. Your goal is to fill the bag completely.
For example, if n=10 and a=[1,1,32] then you have to divide the box of size 32 into two parts of size 16, and then divide the box of size 16. So you can fill the bag with boxes of size 1, 1 and 8.
Calculate the minimum number of divisions required to fill the bag of size n.
Input
The first line contains one integer t (1≤t≤1000) — the number of test cases.
The first line of each test case contains two integers n and m (1≤n≤1018,1≤m≤105) — the size of bag and the number of boxes, respectively.
The second line of each test case contains m integers a1,a2,…,am (1≤ai≤109) — the sizes of boxes. It is guaranteed that each ai is a power of two.
It is also guaranteed that sum of all m over all test cases does not exceed 105.
Output
For each test case print one integer — the minimum number of divisions required to fill the bag of size n (or −1, if it is impossible).
题意:给你一个数 n ,然后给你 m 个2的整数幂的数,这些数可以分解;问你这 m 个数在组成 n 的情况下最小分解数;
看到 2 的整数幂自然而然想到与二进制相关,这题主要就是贪心和二进制关系的理解;
代码贴上,证明不太会
#include<bits/stdc++.h>
#define ll long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
//ios::sync_with_stdio(false);
using namespace std;
const int N=100100;
const int M=200100;
const ll mod=998244353;
int main(){
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--){
ll n,m,ans=0,sum=0,x;
cin>>n>>m;
multiset< ll,greater<ll> >se;
for(int i=1;i<=m;i++){
cin>>x;
se.insert(x);
sum+=x;
}
if(sum<n) cout<<-1<<endl;
else{
while(n){
ll a=*se.begin();
se.erase(se.begin());
if(a<=n){
n-=a;
sum-=a;
}
else if(sum-a<n){
++ans;
se.insert(a>>1);
se.insert(a>>1);
}
else sum-=a;
}
cout<<ans<<endl;
}
}
return 0;
}