CF 1003D Coins and Queries【位运算/硬币值都为2的幂/贪心】

Polycarp has n coins, the value of the i-th coin is ai. It is guaranteed that all the values are integer powers of 2 (i.e. ai=2d for some non-negative integer number d).

Polycarp wants to know answers on q queries. The j-th query is described as integer number bj. The answer to the query is the minimum number of coins that is necessary to obtain the value bj using some subset of coins (Polycarp can use only coins he has). If Polycarp can't obtain the value bj, the answer to the j-th query is -1.

The queries are independent (the answer on the query doesn't affect Polycarp's coins).

Input
The first line of the input contains two integers n and q (1≤n,q≤2⋅105) — the number of coins and the number of queries.

The second line of the input contains n integers a1,a2,…,an — values of coins (1≤ai≤2⋅109). It is guaranteed that all ai are integer powers of 2 (i.e. ai=2d for some non-negative integer number d).

The next q lines contain one integer each. The j-th line contains one integer bj — the value of the j-th query (1≤bj≤109).

Output
Print q integers ansj. The j-th integer must be equal to the answer on the j-th query. If Polycarp can't obtain the value bj the answer to the j-th query is -1.

Example
Input
5 4
2 4 8 2 4
8
5
14
10
Output
1
-1
3
2

#include<cstdio>
#include<string>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
#include<cctype>
#include<stack>
#include<sstream>
#include<list>
#include<assert.h>
#include<bitset>
#include<numeric>
#define debug() puts("++++")
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a,b,sizeof(a))
#define sz size()
#define be begin()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
#define all 1,n,1
#define rep(i,x,n) for(int i=(x); i<(n); i++)
#define in freopen("in.in","r",stdin)
#define out freopen("out.out","w",stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
typedef pair<int,int> P;
const int INF = 0x3f3f3f3f;
const ll LNF = 1e18;
const int N = 1e7 + 20;
const int maxm = 1e6 + 10;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int dx[] = {-1,1,0,0,1,1,-1,-1};
const int dy[] = {0,0,1,-1,1,-1,1,-1};
int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/*
n个硬币,q次询问。第二行给你n个硬币的值(保证都是2的次幂)
每次询问组成x块钱至少需要多少硬币
*/
int n,q;
int a[N]; //之前1e3RE..
map<int,int> m;
int x;
int main()
{
   while(~scanf("%d%d",&n,&q))
   {
       int t;
       m.clear();
       rep(i,0,n)
       {
           scanf("%d",&a[i]);
           m[a[i]]++;
       }
       while(q--)
       {
           int ans = 0;
           scanf("%d",&x);                  //2^30 2^29 ... 2^3=8
           for(int i=(1<<30); i>=1; i/=2)   //由大向小贪心 枚举硬币值(二次方
           {
               int t = min(m[i], x/i);      //选择需要的个数和有的个数的较小数
               ans += t;
               x -= t * i;
               //cout<<"i="<<i<<"  "<<"m[i]="<<m[i]<<"  "<<"x/i="<<x/i<<"  "<<"t="<<t<<" "<<"ans="<<ans<<" "<<"x="<<x<<endl;
           }
           if(x)
           {
               printf("-1\n");
           }
           else cout<<ans<<endl;
       }
   }
}
/*
5 4
2 4 8 2 4
8
5
14
10

1
-1
3
2
*/

猜你喜欢

转载自www.cnblogs.com/Roni-i/p/9348667.html
今日推荐