Educational Codeforces Round 82 (Rated for Div. 2) D题

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值