思路:留意到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; }