思路:留意到k值不大,可以枚举所有面值的钱各k张能得到多少金额,排序二分查找即可。
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <vector>
# define LL long long
# define INF 0x3f3f3f3f
using namespace std;
vector<int>a[21];
int main()
{
int n, k, q, num, ans;
while(~scanf("%d%d",&n,&k))
{
for(int i=1; i<=20; ++i)
a[i].clear();
for(int i=0; i<n; ++i)
{
scanf("%d",&num);
for(int j=1; j<=k; ++j)
a[j].push_back(j*num);
}
for(int i=1; i<=k; ++i)
sort(a[i].begin(), a[i].end());
scanf("%d",&q);
while(q--)
{
scanf("%d",&num);
ans = INF;
bool flag = false;
for(int i=1; i<=k; ++i)
{
for(int j=0; j<a[i].size(); ++j)
{
if(a[i][j] == num)
{
ans = min(ans, i);
flag = true;
break;
}
if(a[i][j] > num)
break;
for(int t=i; t<=k-i; ++t)
{
int pos = lower_bound(a[t].begin(), a[t].end(), num-a[i][j]) - a[t].begin();
if(pos < a[t].size() && a[t][pos] == num-a[i][j])
ans = min(ans, i+t);
}
}
if(flag)
break;
}
if(ans == INF)
{
puts("-1");
continue;
}
else
printf("%d\n",ans);
}
}
return 0;
}